        _        _ _   _    _    __  __
  _ __ (_)_ __  (_) | | |  / \   \ \/ /
| '_ \| | '_ \ | | |_| | / _ \   \  / 
| | | | | | | || |  _  |/ ___ \  /  \ 
|_| |_|_|_| |_|/ |_| |_/_/   \_\/_/\_\
              |__/                     
                            by smea



I - Cubic Ninja userland exploit (aka ninjhax, entrypoint)

	Description : Cubic Ninja (a game published by Ubisoft) contains a level editor. User-made levels can be saved to the gamecard's save partition and shared with other users through QR codes (and, in the japanese version, streetpass). Once the encryption and compression (blowfish and some lz variant, respectively) schemes are understood, it is possible to generate your own custom level QR codes which the game will read.

	Problem : the format that the levels are stored in contains variable-length elements. When parsed, those elements are routinely loaded to fixed-size buffers located on the stack, with the length of the elements in question left unchecked. Of course, this leads to a trivially-exploitable stack smash, which gives us ROP capabilities. It should be noted that the entire level file is loaded to the heap beforehand and that there is no limit to level file size, making it extremely convenient. Worse still, it is possible to trigger the exact same crash with a forged QR code.

	Limitations : this gives us ROP capabilities, not code execution. QR codes can't have an unlimited size, and the stack isn't huge either. We overcome the first limitation with exploit II and the second one by downloading a secondary payload through http:C. Also, Cubic Ninja does not have have either SD or ldr:ro access (see exploit III for why the latter matters).

	Fix : fixing this with the game's source code should be trivial; just add a few well placed size checks. Fixing it without the source code would be more difficult. It shouldn't be hard to write a piece of code that will scan the savegame to check that the .map files located under the /edit/ directory are sane; however, that would not be enough as the QR code reading would still be exploitable. With that in mind, it might be possible to hack up the game's compiled code to prevent the crash, though the solution won't be pretty.
	To be more precise, the problem seems to lie mainly with the function located at 0x001F5F38 (in EU/US version, haven't checked JPN). This function seems designed to copy data a packed structure to some external buffer. It takes as arguments a pointer to the source-data struct (R0), a pointer to the destination buffer (R1) and the size of the destination buffer (R2); it fails if the input data is bigger than the output buffer. This makes it seem safe ! However, it includes a "backdoor" : when R2 is 0, there are no checks made on the input data size. Unfortunately, this R2 = 0 backdoor is used throughout the game's code, often with stack buffers, making it very unsafe. The good news is that it's possible that by patching the code to specify a proper R2, the crash will be fixed. Unfortunately the code usually does not seem to check for errors output by function 0x001F5F38, so that might not quite be enough, but it'd be a start.


II - GPU DMA exploit (aka gspwn, ssspwn, gpuhax, The Real Deal)

	Description : the 3DS's GPU is capable of accessing certain sections of memory with reading and writing capabilities. These regions include VRAM and parts of FCRAM. This is used for a number of things, including commands which let us use the GPU to copy data across memory regions through the gsp module, reading texture/vertex object data, or writing to the framebuffer when rendering.

	Problem : while the GPU having access to these regions of memory isn't necessarily an issue, the fact that gsp doesn't do *any* checks on input/output addresses for GPU commands it processes definitely is. The GPU has read/write access to the entire 0x20000000-0x26800000 memory range, and it is therefore possible to access those regions by using GX commands 2, 3 and 4. This "thankfully" leaves out the SYSTEM memory region at the end of FCRAM (intentional ?), but still opens the door to easily obtainable code execution as well as other types of attackes (time of use/time of check comes to mind).

	Limitations : while this lets us execute native code by overwriting the currently running application's .text region, it doesn't immediately let us do much more. Every other currently running application has its .text hidden away in the 0x26800000+ memory region, including home menu.

	Fix : the fix for this is, interestingly enough, both trivial and fairly elaborate. The thing to see here is that there are (at least) three ways of exploiting this :
			- GX commands : this is the easiest one to fix. You should simply add checks to your handlers for commands 2, 3 and 4. Not sure exactly how you want the checks to work (ideally should only allow the address to be within actually mapped LINEAR heap, but not sure if you have an easy way of doing that with your system), but it should be very doable.
			- WriteHWRegs/WriteHWRegsWithMask : it's possible to manually mimic the sequence of register reads/writes used by GX command handlers from a usermode application. This means that the above fixes can be bypassed fairly easily. Therefore, you should add similar fixes to the handlers for those commands when writing to certain registers.
			- Rendering : this is the tricky one. The first time I exploited this vulnerability, I did so by rendering a scene with the framebuffer set to output to my application's .text region. To prevent this, you would have to scan GPU command buffers sent with GX commands 1 and 5 for framebuffer setting GPU commands. This is made more difficult by the fact that it's possible to group GPU commands together and to mask GPU command parameters (I think). Because of that, a simple filter could potentially be tricked into letting malicious framebuffer-setting something through if not done correctly. Another issue is that it should be possible for usermode apps to reproduce the sequence of GPU register read/writes used in GX commands 1 and 5 and again completely bypass whatever checks were put in place in the handlers for those commands.


III - ro takeover exploit (aka rohax)

	Description : the 3DS runs a system module named "ro" (for relocatable object probably ?) which allows users to load and run dynamically linked code ("CROs"). These CROs are most commonly stored directly in romfs and are checked with a central CRR file which is signed and contains hashes for each CRO file in the application. The CRR's signature is checked once when that file is loaded, and then each CRO's integrity is checked by comparing it against the corresponding hash stored in the CRR file. CRO files contain a list of patches which must be applied to the code being loaded so that it can be relocated. The ro system module has access to a number of high-privilege system calls which, among other things, allow it to give regions of memory executable status within its own virtual memory space as well as other processes'.

	Problem : using exploit II, we are able to modify the loaded CRR file's hash list *after* the signature check has occured. This, in turn, lets us load arbitrary CRO files. It is then possible for us to manufacture a custom CRO which will use the relocation patch list to patch ro's stack, give us ROP capabilities within ro and use that to get ro code execution using SVC 0x70. This is not supposed to be possible as relocation patches can only be within CRO segments, and CRO segments are checked to be within CRO memory when first parsed, which is great. However, what we can do is extend one of the CRO segments to include the CRO segment table (which is within the CRO itself, not copied elsewhere for actual use), then use our first relocation patch to extend a CRO segment to include the stack, and then use subsequent CRO patches to write our ROP chain to the stack.

	Limitations : getting code execution in ro is great because it gives us access to svcControlProcessMemory, which lets us map memory as executable within other processes. It also allows us to modify other processes' memory using svcMapProcessMemory. That being said, we can't do that with just any other process (like, ideally, loader...) as we need a handle for that other process, and ro does not have access to svcOpenProcess. Therefore, we only use our code execution capabilities within ro to remap memory within Cubic Ninja.

	Fix : it's true that fixing exploit II would prevent us from exploiting this. However, there is no guarantee that another bug in another part of the system wouldn't allow us to do something similar to exploit II. Because of that, potential fixes include :
		- check the CRR's signature every time you check a CRO hash.
		- copy the CRO segment to somewhere outside of the CRO when you first parse it.


IV - Bonus Round (aka spiderto, or "not really an exploit but that's how we get access to the SD card and ldr:ro from Cubic Ninja")

	Description : the 3DS can run applets simultaneously to the main application. These applets include the home menu and the web browser (aka spider). It is possible to launch such an applet from any usermode app thanks to APT commands.

	"Problem" : while system applets such as spider keep their .text in the 0x26800000+ region, they use the heap to store information, including stacks for secondary threads. This allows us to takeover that thread using exploit II and appropriate timing, and from there takeover spider's main thread, and use that to run rohax, all through ROP. From there, we use NS:SendParameter to give Cubic Ninja spider's ro and fs session handles.

	Limitations : N/A

	Fix : N/A


Summary exploit sequence :

	- ninjhax => Cubic Ninja ROP
	- Cubic Ninja ROP => gpuhax => Cubic Ninja code execution
	- Cubic Ninja code execution => gpuhax => spiderto => spider ROP
	- spider ROP => rohax => ro code execution (ro becomes "hb" custom service handler)
	- ro code execution => Cubic Ninja code execution with memory remapping and basic cache management capabilities

V - Recommendations

	The number 1 priority should be to fix exploit 2 (gspwn). It's the most important part of this process, and removing it breaks everything else. Fixing the entrypoint is good but entrypoints aren't very hard to come by. Fixing rohax is good but we don't *need* rohax to run code. gspwn is really the biggest threat and the one that should be eliminated first and foremost.
