
1979 changes to exploits/shellcodes Couchdb 1.5.0 - 'uuids' Denial of Service Apache CouchDB 1.5.0 - 'uuids' Denial of Service Beyond Remote 2.2.5.3 - Denial of Service (PoC) udisks2 2.8.0 - Denial of Service (PoC) Termite 3.4 - Denial of Service (PoC) SoftX FTP Client 3.3 - Denial of Service (PoC) Silverstripe 2.3.5 - Cross-Site Request Forgery / Open redirection SilverStripe CMS 2.3.5 - Cross-Site Request Forgery / Open Redirection Silverstripe CMS 3.0.2 - Multiple Vulnerabilities SilverStripe CMS 3.0.2 - Multiple Vulnerabilities Silverstripe CMS 2.4 - File Renaming Security Bypass SilverStripe CMS 2.4 - File Renaming Security Bypass Silverstripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities SilverStripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities Silverstripe CMS 2.4.7 - 'install.php' PHP Code Injection SilverStripe CMS 2.4.7 - 'install.php' PHP Code Injection Silverstripe Pixlr Image Editor - 'upload.php' Arbitrary File Upload SilverStripe CMS Pixlr Image Editor - 'upload.php' Arbitrary File Upload Silverstripe CMS 2.4.x - 'BackURL' Open Redirection SilverStripe CMS 2.4.x - 'BackURL' Open Redirection Silverstripe CMS - 'MemberLoginForm.php' Information Disclosure SilverStripe CMS - 'MemberLoginForm.php' Information Disclosure Silverstripe CMS - Multiple HTML Injection Vulnerabilities SilverStripe CMS - Multiple HTML Injection Vulnerabilities Apache CouchDB 1.7.0 and 2.x before 2.1.1 - Remote Privilege Escalation Apache CouchDB 1.7.0 / 2.x < 2.1.1 - Remote Privilege Escalation Monstra CMS before 3.0.4 - Cross-Site Scripting Monstra CMS < 3.0.4 - Cross-Site Scripting (2) Monstra CMS < 3.0.4 - Cross-Site Scripting Monstra CMS < 3.0.4 - Cross-Site Scripting (1) Navigate CMS 2.8 - Cross-Site Scripting Collectric CMU 1.0 - 'lang' SQL injection Joomla! Component CW Article Attachments 1.0.6 - 'id' SQL Injection LG SuperSign EZ CMS 2.5 - Remote Code Execution MyBB Visual Editor 1.8.18 - Cross-Site Scripting Joomla! Component AMGallery 1.2.3 - 'filter_category_id' SQL Injection Joomla! Component Micro Deal Factory 2.4.0 - 'id' SQL Injection RICOH Aficio MP 301 Printer - Cross-Site Scripting Joomla! Component Auction Factory 4.5.5 - 'filter_order' SQL Injection RICOH MP C6003 Printer - Cross-Site Scripting Linux/ARM - Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (28 Bytes) Linux/ARM - sigaction() Based Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (52 Bytes)
6.6 KiB
For those who only care about one thing: the PoC is here. Mirror: https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/41021.zip
Overview
Cemu is a closed-source Wii U emulator developed by Exzap. New versions are released to those who donate to him via his Patreon first, then to the public one week later. According to its official website, Cemu "is not intended for general use yet", however it can run some games well.
It HLEs the Wii U OS APIs. For those who don't know, the Wii U runs executables in a modified ELF format that include additional PE-like import and export sections. Basically, the HLE here means each exported function from each shared library has been reimplemented, and runs in native code. That's a pretty large attack surface! So, when looking for bugs, I decided to start there.
Finding bugs in Cemu HLE API emulation
Obviously, the first thing to do is to find where the API exports are set up so all of them can be annotated in IDA. I found a function at 0x1400AEDC0
(before relocation, cemu.exe is compiled with ASLR) that I labeled set_up_emulated_API
. It takes three arguments: a pointer to a hashed (or obfuscated) shared library name, a pointer to a hashed (or obfuscated) exported function name, and a pointer to the function used for implementation. This function has a nice debug printf
where it printed out the library name and exported function name, so I did things the long way and set a breakpoint there in x64dbg and labeled all the ~620(!) functions by hand. This took the better part of a day (however I did take breaks.)
Once I had all the functions labeled, I could go ahead and start looking for bugs. It was nice from my perspective that the emulated API functions did all the grunt work of endianness conversion of arguments and return values, so I didn't have to do anything of the sort myself. I first decided to check the more interestingly (for me) named functions, not long later I'd found a bug.
sysapp!_SYSGetSystemApplicationTitleId
uint64_t _SYSGetSystemApplicationTitleId(uint32_t index);
The implementation of this function just sets up a large array of title IDs (a title ID is a 64 bit integer that identifies "something that runs on the console", like a system application, firmware component or game, this has been used by Nintendo since the Wii and DSi, on console and handheld respectively) on the stack, then indexes it using the provided argument without checking and returns the array[index] to the emulator. What a perfect infoleak, to defeat ASLR later!
Exploiting this seems easy, just get the return address from the stack (index 37
), but it seems this isn't totally reliable, so instead I make a dummy call, then use index 52
, which seems to return an address inside the cemu.exe
.text
more reliably.
padscore!KPADSetConnectCallback
uint32_t KPADSetConnectCallback(uint32_t index,uint32_t value)
With an infoleak obtained, I just needed to find some (semi-)arbitrary write, and this took annoyingly longer to find. I found a few bugs that seemed promising but ultimately turned out to be unexploitable. Finally, after checking some of the functions not related to the OS, I found this function. Basically, it writes to an array of 32-bit integers (obviously the intended use of that array is function pointers inside the emulated system), in the .data
section, with no checking of the provided index. Even better, it returns the old value (although I never needed to use this functionality when exploiting).
The array is unfortunately near the end of .data
, but that doesn't really matter, as it's stored before a nice array of KPAD C++ objects with vtables that I can clobber -- and if a pointer inside one of the objects happens to not be NULL, this same function makes a vtable call twice! Even better!
Exploitation
My PoC clobbers the first KPAD object (player 1 gamepad): it nulls out the checked pointer so no vtable calls are made while things are being overwritten, it overwrites the vtable pointers, sets up the ROP chain, sets up the stack pivot, makes that pointer non-NULL, and makes a dummy call to KPADSetConnectCallback
to get ROP.
Heh, I just made that sound easy. It wasn't.
Let's see, it was annoying to find a stack pivot in the first place? But then I found the perfect pair of gadgets:
0x000000014015d404 : add rcx, 0x10 ; jmp qword ptr [rax]
0x0000000140228371 : push rcx ; pop rsp ; ret
When the first one gets called, rcx
has the address of the vtable array, and rax
has the address of the first element of the vtable array (which isn't actually used, so it's a perfect place to put a gadget address).
The ROP chain is written using KPADSetConnectCallback
just like everything else, all this is written into a part of memory that contains UTF-16LE strings for controller mappings, that can only be seen if you open the controller settings. The ROP chain itself just grabs the address of the shellcode inside emulated RAM, memcpy
s it to RWX memory allocated for the dynamic recompiler, and jumps there. Sure, it doesn't work if you deliberately disable the dynamic recompiler, but firstly, who even does that?!, and secondly, I'll leave the making of a ROP chain that uses VirtualAlloc
to someone else if they wish.
The shellcode itself is just metasploit windows/x64/exec
running calc.exe
. Nothing special.
One final thing: when testing, I noticed that the emulator crashed if controller one was set up properly. It's because I initially thought the pointer that got checked for being NULL was a boolean or something else, and I'd only zeroed out the lower 32 bits of it. Whoops.
Compiling the PoC
Linked at the top of the page is an archive including the PoC itself as calc.rpx
plus source plus modified and additional import library dependencies (as source and binaries). I used wut to make the PoC which obviously depends on devkitPro/devkitPPC. After compiling wut successfully I had to make library additions, as both of the vulnerable functions were not included in the library set. Luckily enough it was very easy to make additions to the import libraries.
Timeline
2016-12-30: started reversing
2016-12-31: found exploits
2017-01-01: made PoC, made initial contact with developer
2017-01-02: developer replies, said fixes have been made
2017-01-02: asked for release date
2017-01-02: reply: release date unknown, "in 1-2 weeks maybe"
2017-01-09: release to patrons, public disclosure