So what about the libtiff vulnerability?
Important: This article is NOT related to Matiaz’s “eggsploit” but to another vulnerability discovered months before that.
Ok, so I brag about how you can find exploits, yet I’ve been very quiet myself about my own attempts at it. Well that’s because I’ve not been successful so far. This post is a mix of bad news and good news, so read on if you’re interested.
What is this about?
A few months ago, I came across a bug in the libtiff library. As you may or may not know, the PSP uses this library for TIFF images decoding. This bug has been half-patched (I’ll talk about the “half” part later in this article) in firmware 4.21, but this was interesting because the first PSP3000 packages shipped with firmware 4.20.
If you want to read more about this, please go to lan.st, that’s where everything’s explained.
The point is, there was a buffer underflow vulnerability, and that was a possibility to have an exploit.
Why isn’t there a Proof of concept yet?
This one is easy: I never managed to turn the bug into an exploit. However I am so close that it gets on my nerves. I decided that I spent too much time working on this so I gave up, but I still have the hope that someone might use this successfully (as a matter of fact, someone DID use this successfully).
Here’s what’s going on on the PSP:
First we launch usbsfhost_pc.exe and psph.exe on the PC. On the PSP, we launch PSPLINK from the Game menu. In pspsh, we need to type the following commands to start the XMB from PSPLink:
Now that this is done, I am in the XMB, and I go to the photo folder, that contains the crafted tiff file. I do that the same way as I did in my youtube video (except I’m doing all that with PSPLink running, remember?)
What happens when the PSP crashes? Well, the following:
as you can see, my crafted value ends up in $v1 (0x61616161), and the PSP crashes when it tries to load something from an address that doesn’t exist (0x616161B9, which is 0x61616161+88).
Ok, but wait, there’s nothing interesting here, right? I told you recently that we need $ra or $sp to contain cool values, correct? Yeah, well, as I told you, it’s always better to look at the code to make sure of what’s going on. The code crashed at address 0x09B25584 (that’s the value of the EPC), so let’s see what it looks like there.
Ok, so the code loads a value into $v0 by reading it at [contents of $v1]+88, and then performs a jump at… $v0!!! So that’s it, I’ve got my jump!
If I can craft my image to put 1) a real address instead of 0x61616161 (for example, 0x08800000), and, at this address, another real address (say, 0x08900000), well I can have the code jump to 0x08900088.
Now let me tell you a secret, it’s quite easy to do that, I’ve done it, and you can do it too if you play with the inject.rb file (link at the end of the post)
I can jump to an arbitrary address, so what’s the problem?
Well… there are 2 issues actually. The first one is that even if I can jump to wherever I want, I didn’t find any way to inject code at a specific location yet. I tried to load other images before the crafted tiff, it only half worked, and the code never ends in a reliable position in memory. I tried the tiff itself, but theoretically it cannot accept more than 256 bytes of code, and practically, I never managed to input more than 30-40 bytes in it. It’s close to impossible to have something running with so little flexibility.
The second issue is that I didn’t show you the whole dump… there is actually another thread crashing. And when a thread crashes, the PSP shuts down.
So even if I could solve the first issue (where to put the code), this thread would still crash, and take the PSP down with it. So what is this thread ? Well that’s easy, it’s the decoding thread, the exact same one I’m using to create the underflow.
As I am in an infinite loop, the underflow never stops, and end up trying to write to an invalid address (0x087FFFFF… 0x08800000 being the beginning of the user RAM)
So what needs to be done?
Easy: find a reliable way to input code into RAM before using the crafted tiff. (With a crafted png that we display just before the tiff? a crafted mp3 that plays while we look at the image? There are probably dozens of solutions for that, but I could’nt find anything reliable).
Once this is done, I guess the first thing the code should do is stop the underflow, by changing the code that decreases the value of $a0 into something less dangerous such as a nop.
As I said, easy, right? Well, I don’t know how to do all this. Stopping the underflow shouldn’t be too big of an issue once we know where to put code to run…but that’s the issue right now.
And what about firmwares above 4.20? I saw a crash on 5.02 too!
The fact is that the bug hasn’t been correctly solved. However, it’s been patched enough to prevent anything useful from happening with this vulnerability beyond firmware 4.20