Now Reading
Hacking the Nintendo DSi Browser

Hacking the Nintendo DSi Browser

2023-03-03 13:29:37

I managed to take advantage of the Nintendo DSi browser 15 years after it was launched in Japan. This submit will go over the journey and the technical particulars.

To see the exploit in motion, try the video. The exploit is offered on GitHub. In order for you a fast overview, you possibly can skip to the TL;DR part.

Motivation

I began wanting on the browser early in the summertime of 2022. My preliminary thought was to make a cursed pwn chal for UIUCTF 2022. I assumed that with the DSi’s age and lack of safety mitigations, I might provide you with an exploit in a weekend. That estimate was waaaay off. I ended up being consumed by the undertaking on and off for round 6 months earlier than lastly arising with one thing to indicate for it.

Some Background

The DSi browser makes use of Opera 9.50. There aren’t any safety mitigations in any respect. Leaping to shellcode is again on the menu! Stack buffer overflows are viable. Exploiting use-after-frees, which are sometimes common in browsers, is simpler than ever. Actually, the DSi doesn’t even have an working system, so there’s no kernel to take advantage of. Numerous system privileges are dealt with by the SCFG register. The browser has sufficient privileges to run most homebrew, however not sufficient to achieve persistence throughout boots with out one other exploit.

Assets

We don’t have supply code and even symbols for the browser. Nonetheless, there are a number of assets which are useful for hacking DSi issues:

  • melonDS – A DSi emulator which might emulate the house menu, browser, and Wi-Fi!
  • melonDS GDB stub – Permits us to attach GDB to the emulator to debug crashes
  • GBATEKPhenomenal documentation about DSi internals
  • DSi Mode Hacking Community – A number of very educated and useful individuals right here to assist with something DSi

Google-fu?

Naturally, I began googling for Opera bugs hoping to search out one thing simple. exploit-db gave numerous promising outcomes. I used python’s HTTP server to host the POCs on my laptop computer and pointed the browser operating in melonDS at it. I analyzed the ensuing crashes within the melonDS output. Sadly, I discovered that I both couldn’t reproduce the bugs, or that they didn’t trigger fascinating crashes.

Webkit Structure Take a look at Fuzzing

MrNbaYoh wrote up their 3ds exploit “validityhax” here. Within the submit, they discovered bugs by sending the browser all of WebKit’s structure assessments. The instinct is that the WebKit structure assessments have bizarre edge circumstances or regression assessments which might trigger issues on WebKit implementations which are outdated. This is sensible for the 3ds browser, for the reason that 3ds browser makes use of WebKit. Wouldn’t it work on the DSi? One technique to discover out.

I arrange a flask app which sends a take a look at case in an iframe. When the take a look at is completed loading, the web page refreshes itself to request a brand new take a look at from the flask app. Finally, the flask app consumes all ~100k HTML take a look at information from the WebKit structure assessments. We will spin up an arbitrary variety of emulators to check in parallel.

4 melonDS emulators receiving WebKit layout tests in parallel

The outcomes have been underwhelming. There have been numerous null dereferences which I marked off as unexploitable. Because it seems, there may be really information mapped close to tackle 0 on the DSi, nevertheless it’s not writable. The assessments yielded another bizarre crashes, however the underlying downside wasn’t apparent from the wanting on the take a look at case which brought on it. Understanding the crash would take severe reversing work which I positive wasn’t going to do with out symbols.

At this level, the undertaking went on maintain as I began one other semester of faculty. However by the point winter break got here, I had some new concepts to attempt.

Heap Speculation

My speculation was that possibly the structure assessments did have fascinating heap bugs, however we simply didn’t have a dependable technique to detect them. For instance, if a use-after-free occurred, however no new information was written to the freed reminiscence, we wouldn’t even observe a crash. If we had a Home windows or Linux construct of Opera 9.50, we might use some heap debugging instruments to catch heap bugs as an alternative of letting them crash non-deterministically.

This despatched me on an hour-long search to discover a construct of Opera 9.50. The Wayback Machine got here to the rescue. I checked Opera’s previous obtain web page, however discovered that the downloads weren’t archived. The obtain web page did give the filename, although, which I might google for. From Google, I discovered a handful of dwelling websites which miraculously had the file. I crosschecked the md5sum throughout the websites and located that they matched. In the long run, I couldn’t discover a Linux construct, however a Home windows construct will do.

Wine has heap debugging options which may be enabled utilizing WINEDEBUG=warn+heap. This may fill freed reminiscence with a canary worth 0xfeeefeee in order that use-after-free bugs usually tend to trigger a crash. In a crash dump, it is going to be apparent a use-after-free is concerned if we see the canary worth. Let’s rerun the structure take a look at fuzzing with wine. My full command to run this historic Opera model underneath wine was WINEDEBUG=warn+heap WINEPREFIX=$HOME/.wine32 WINEARCH=win32 winedbg --gdb opera.exe

The Bug

One of many structure take a look at crashes which was initially regarded as an unexploitable null dereference turned out to be a use-after-free!
use-after-free crash

The lowered code which causes the crash is the next with feedback added by me:

// mediaRule.cssRules.size begins at 0

mediaRule.insertRule(".test2 { shade: blue; }", mediaRule.cssRules.size);

// mediaRule.cssRules.size is now 1

attempt {
  // fails with syntax error and throws javascript exception
  mediaRule.insertRule("@media display screen { p { shade: crimson; } };", mediaRule.cssRules.size);
} catch (e) {
}

// mediaRule.cssRules.size is now 2 O.o
// refreshing web page causes the crash

There’s something bizarre occurring right here, since in idea, including a rule which causes a JavaScript exception to be thrown mustn’t change the size of the cssRules array.

That being mentioned, all we have now here’s a learn from an tackle we might presumably management, which can or is probably not exploitable in of itself. I don’t need to do any reversing work, so let’s attempt to mess around with these corrupted JavaScript objects to see if we will get a write or a leap as an alternative.

See Also

Because it seems, we will get a leap to 0xfeeefeeee by including the next after the earlier excerpt:

// filter out mediaRule.cssRules
mediaRule.deleteRule(0);
mediaRule.deleteRule(0);

// accessing this property causes leap to 0xfeeefeee
mediaRule.cssRules.size;

If I needed to guess, some reminiscence backing cssRules is getting freed after the final deleteRule invocation and there may be some vtable shenaniganry occurring when accessing its size. However once more, I don’t know, since I’m not going to do any reversing work. The less mitigations which exist, the much less we have to perceive concerning the bug to take advantage of it.

Exploitation

The excessive degree aim is obvious: spray NOP sled adopted by shellcode, then reclaim the freed reminiscence and write the tackle of our NOP sled.

With a purpose to reclaim the freed reminiscence, we have to allocate one thing across the similar dimension because the freed chunk. For exploitation on fashionable browsers, issues like Float32Arrays are a preferred selection. Sadly, we’re engaged on an historic browser which doesn’t have these options. Trying to see what the opposite exploits on historic browsers do, I discovered that str2hax creates canvases and resizes them to make exact allocations. This works nice on the DSi as effectively. Filling within the RGBA pixels of the canvas provides us exact management over the reminiscence.

The exploitation circulation is as follows:

  1. Create a number of canvases with a particular width and top = 1
  2. Do the insertRule/deleteRule bug to free mediaRule.cssRules
  3. Write the tackle of our NOP sled to all of the canvases within the type of RGBA pixels. This may reclaim the freed reminiscence as a result of the drawing code will allocate the right dimension chunk. The tackle of our NOP sled is discovered from the debugger and is comparatively constant because of no ASLR. This allows us to hard-code an tackle in our payload.
  4. Spray our NOP sleds and shellcode
  5. Consider mediaRule.cssRules.size; to leap to our NOP sled

This works on melonDS… typically! Let’s name the freed pointer freed_ptr. The reminiscence it factors to is what we reclaimed and wrote our NOP sled tackle to. It seems that round half the time, the browser will leap to *freed_ptr, which is nice for us and according to what we noticed underneath wine. The opposite half the time, it’ll leap to **freed_ptr, which tries to dereference a NOP instruction and leap there. That crashes in fact. However that is a straightforward repair! The tackle of our NOP sled is “NOP sufficient” when handled as an instruction. This implies we will use the tackle of our NOP sled because the NOP instruction itself, which satisfies each of the circumstances.

Payload

Now that we have now an exploit which works considerably reliably, we have to select helpful shellcode. Trying to different DSi exploits, it’s widespread to make use of minitwlpayload which hundreds boot.nds from the SD card and executes it. That is usually one thing like TWiLightMenu. Placing all of the items collectively, we will have a good time with a completely working exploit on actual {hardware}.

Thanks

TL;DR

  1. The DSi makes use of Opera 9.50, so Google for current Opera 9.50 exploits and take a look at them. No luck on melonDS emulator.
  2. Ship the browser all of WebKit’s structure assessments. No luck on melonDS.
  3. Discover Opera 9.50 Home windows construct and run underneath wine
  4. Allow wine heap debugging with WINEDEBUG=warn+heap WINEPREFIX=$HOME/.wine32 WINEARCH=win32 winedbg --gdb opera.exe to catch use-after-frees
  5. Attempt WebKit structure assessments once more underneath wine
  6. Discover a use-after-free, mess around with corrupted objects, get it to leap to an tackle we might presumably management
  7. Reclaim freed reminiscence utilizing canvas trick from str2hax
  8. Develop full exploit on melonDS emulator
  9. Confirm exploit on actual {hardware}

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top