How to dump the bootldr[edit source]
Wow... such hostility against me just cause I said that one my future projects was trying to adapt the btldr exploit to hardware so we can hack (ie run unsigned code) on all consoles. I think I deserve the opportunity to explain myself before you start doubting me.
That means releasing the btldr exploit (which it patchable) before the others devs can even check if its remotely possible but it is the only way to get redemption so let's start...
DUMPING THE BOOTLDR[edit source]
As you know the bootldr is one of the two loaders that are signed per console and it was the only part of the system that haven't been hacked.
Once you load it the same way as metldr (via SigNotify) it would start requesting different addresses that we don't control. You can take a look on my user page to the dma sequence that it produces.
As you see it access a lot of different addresses and we don't have control of any of them so the first objective was to control the input/output.
The sandbox[edit source]
The objective was to redirect the flows of data to our controlled buffers so we know what is written or read. To achieve that a driver was created.
This driver performs two functions: - the first is creating lv1 peek/poke using the patched lv114 that comes with OtherOs++ and other CFW. - the second is reserve a block of consecutive memory that would be used as an HTAB.
The SPU is told to use our HTAB which in turns redirects to our user buffers. To get the physical address... the user pages are locked on memory and then using an old trick found by geohot their real address is retrieved.
At this point we have control of what the SPU reads BUT if consecutive small accesses are done we have no control if we want to change something in between.
The first exploit[edit source]
I'm calling this an exploit but actually is a bad implementation of a feature cause it should be disabled on isolation. The feature is called the MFCLSACMP. Basically is a register on the spu that is checked before doing a dma op. If the source/target address on the SPU is inside the mask defined by this register then dma is stopped and an interruption is reported. Until this interrupt is cleared the dma is not started.
Great, so we control what it reads and when it is read... the first objective was achieved total control of the I/O. That is what you can see on my user page on wiki.
However this all so allowed me to find the biggest problem on using the booldr as an oracle.... the config ring.
The config ring is a series of bits that syscon sends to the cell before during the power up.... On this cell implementation the config ring is accessible from inside the spu as a read once channel. So unless I could find a way to refill the channel the bootldr couldn't be used as oracle. Even worse at this point I didn't know how the config ring was read (although an undocumented channel was on top of the list).
I spent a couple weeks trying to figure the problem. Finally I posted the log on the wiki looking for help. Obviously some approach. We exchanged info. I gave then the tools and they gave me means of validating my hypothesis (those on the log)
We worked a lot of time on this. Remember that I was trying to get an oracle not an exploit so filling the config was a must... several thing were tried but none worked.
After a month or so I started checking other projects while thinking of what to do. Then after several months I decided to try to exploit it instead of using it.... given the log the entry point was clear...
The bootldr exploit[edit source]
If you see the log (#Logs) you'll see a lot of data exchanging between the spu and the syscon. graf had described it on his bible so it was known... but the log also said that the data was read twice once to read the header and once to read header + data.
On the header was a variable length. So I decided to change the len between both reads.... didn't work until i corrected also the chksum... and then BINGO! unexpected behavior... a possible exploit was found.
The advantage of this exploit is that it gave us a lot of points to test. The info was shared and two of us friendly raced one against the other to find the correct possibility.
I won the race of finding the execution point although I lost the one for dumping. The winner was command 0x20 which is an info message... casually the config error message... so their own protection had given us the bootldr.
That's the story of the exploit... it was then decided that I got the ultimate decision of releasing the exploit and any of us could leak the keys... however they asked me too hold it until SONY has reacted to the dex conversion and I told them that I would not release them until I got the appldr keys by myself.
I suppose they passed the keys to others and them at some point the keys probably arrived to EXETrimAll and N0DRM (I don't think they exploited trublue...). Meanwhile i was in the middle of my holidays and when I come back they were releasing non-stop so I didn't see that it was necessary to leak them.
Unfortunately they also leaked to a scoundrel that sell the key to discblu.
That forced some one that have the key to make it public.
You said that I'm angry cause someone leak the key... nope. I was angry with discblu... and with some hacker that reappeared just to say that he already knew how to do it. As you can see the method is completely software and does not use the signature bug (except for installing the cfw... but then all the apps need to credit them). If you persist I'll tell you that this can also be done on a 3.15 with geohot pulse exploit.
The code[edit source]
I have attached the code of a working version for latest exploitable slim. I know that also works on other version but I don't know which ones. It is only valid for NOR consoles cause it expects a full NOR flash as one of the parameters. It has two programs. One is a kernel module so it must be load with insmod. The second its a user program that takes as parameter the speID (i recommend using 0 that is normally enabled), the flash file and a debug file with the buffers. the actual dump is WRITTEN TO DUMP.BIN
If the exploit worked you should see the text "Interrup". If it didn't try modifying line 799 correctPacket(0x40, 0, 0); by incresing the first parameter (0x40). Thats the len that is send on the second read.
The dump is shifted by as a side effect of the bug. For me it was 0x800 bytes... but others got different result. The start function must be at 0x400 once shift is corrected
BTW the code is ugly and there is a lot of data that is not used so if someone has questions please ask me (on this or other ps3 related things)... I'll be available until sunday... then I'll definitely leave.
Now I'll explain my idea for the hardware solution.
Improving the exploit[edit source]
THE FOLLOWING IS ALL THEORETICAL AND IT WILL PROBABLY NOT WORK (I'M NOT A HARDWARE EXPERT AND THAT'S THE MOST DIFFICULT PART)
In this case the objective is not dumping the bootldr but get code execution. Using an small payload a program will be copied to spu. That program will just copy a patched unencrypted lv0 to the memory and tell the PPU that code was loaded successfully.
By achieving that we would have full control of the system. Our patched lv0, will load an original lv1ldr (required to get the ATA keys) which will load an original lv1 but before giving control to level1 our level0 will patch it so we still have control. Same with lv2 and vsh.
As I said basically the bug consist of changing the response len between the first read and the second. That is easily done if you control the buffer where the data is located (exploitable consoles). But we want to do this before anything is loaded
So we need to change the comm between syscon and cell before any software outside the cell is loaded... the only option is a hardware interceptor. This hardware will intercept the communications and change it so the exploit is triggered (This is called a man in the middle attack). The payload will be sent as part of the 0x20 command reply... if the bug is trigger properly we know that our payload will start around 0x3E010.
In addition to this I recommend adding a second flash chip that will contain the patched firmware. That will allow the user to go from patched to official with a switch
As you see the device I propose is not a drm device... it actually triggers an exploit similar to the ODE device that whats announced (BTW that is perfectly done with the info that glevand posted).
The questions is: Is all of this possible?... well from the software part I'm pretty sure but I don't know if the hardware can be build or if the cost will be too much.
In any case if it is possible, there is enough info on this post to make it...
Unfortunately there is also a enough info to patch the bug (if they didn't already). However it would only be patchable on factory...
Provided dumps of the bootldr for further analysis[edit source]
- BV 2.7.0, BID 3517,38879, BDate 2009-03-24_23:51:55 : https://dl.dropbox.com/u/35197530/dump.bin
SHA-1: 865729E2E2917134128B397D1237568572F6D2FB http://mir.cr/M21DPLBK
Porting to NAND[edit source]
Problems / needed changes:
- NAND offsets differ from NOR : http://www.ps3devwiki.com/wiki/Flash
- NAND / FLASH controller doesn't have MMIO regions : www.psdevwiki.com/ps3/Talk:Hypervisor_Reverse_Engineering#MMIO_.2F_Memorymap
Solution 1[edit source]
1. comment this:
2. create an empty 16 MB file for your flash dump, then get your bootldr dump and place it to this empty file at offset 0xFC0000
Other References[edit source]
Analysing bootloader Dumps in Ida Pro[edit source]
1. Load Dump into ida pro
2. load this script via file >>> load script https://github.com/techbliss/Bootloader-PS3, to get the functions visible.
Note: you need to change the function analyze_area to AnalyzeArea if you're using the recent released IDA 6.5. in case you're still using 6.1, keep the script as it is. presumably this script also works on metldr dumps as well, since it's also an spu binary dump.