Hello guys,
In 2k16 I got my first iPhone, and introduced myself to iOS platform. And after some months I jailbroke my device. After iOS 9.3 jailbreak by Pangu Team, it was tough for hackers to develop a jailbreak for iOS 10, but in the last months of 2k16, Google's Project Zero team released a 0-day vulnerability in iOS platform, through which Luca Todesco developed a jailbreak for iOS 10. And since then I got attracted towards jailbreaking and iOS kernel hacking.
But it was not easy, I first learned ObjC, then developed some useless tweaks and learned from other developers, but the main problem was to gather information about iOS kernel hacking. Everyone was giving me information about iOS App Hacking. Then I found a 16-year old guy (Billy Ellis), he is also a iOS hacker but he claims himself as a beginner, but he is actually a beast. He showed me right direction towards it and all.
So today I'll be sharing a little introduction to the first jailbreak in iOS history i.e.
24kpwn - 0x24000 Segment Overflow. So I was reading about this exploit and I learned that hacking is not just about hacking into web applications, wordpress, unprotected cams, defacing websites and all.
So let's get started, before starting let me introduce you with some term so that you don't get confuse.
LLB - Low Level BootLoader
SRAM - Static Random Access Memory
IMG3 - New version of IMG2 used during iOS boot.
S5L8720 - Application Processor
S5L8920 - Application Processor
NOR - NOR flash memory(memory that can be erased and reprogrammed electrically)
IDB - Debugging Process
SoC - System on Chip
I think I introduced all the terms which I'll be using in this post.
What is 24kpwn?
24kpwn is also known as 0x24000 Segment Overflow, which was found by some researchers in first iPod Touch 2G, which allowed to bypass the bootrom signature checks on LLB and finally getting the untethered jailbreak. And after that in October 2009 Apple patched this vulnerability.
Background :-
When the device boot up, the S5L8720 and S5L8920 have MIU configuration which maps the Secure ROM to 0x0 address, providing the newly turned on device with an ARM exception vector and the first code to execute. This MIU configuration also maps out some SRAM to 0x22000000 for the S5L8720 and 0x84000000 for the S5L8920. And the statically allocated variable, heap and stack must use SRAM, as Secure ROM is unwriteable. A region of memory starting from (SRAM Start)+0x24000 used as a buffer for loading the next stage of bootloader, which is simply some LLB code stored in NOR. And this NOR is stored with LLB code along with other bootstages codes such as boot logos and all, which is provided to the XNU Kernel. Now the first portion of 0x160 bytes of memory at (SRAM Start)+0x24000 is used for initialized statically allocated variables. And after the boot, values for that region are initialized from Secure ROM.
Vulnerability :-
Now nothing looks fishy here, then where is the vulnerability. The vulnerability was in the code which copies the LLB IMG3 file from NOR into the memory, but it doesn't checks the size of the LLB image being loaded, instead of it it takes the whole size from the non-signatured portion of the IMG3 header of the NOR (ROM Offset 0x2178). Any image greater than 0x24000 bytes in length will begin overwriting the portion of memory used to store Secure ROM statically allocated variables.
And this vulnerable data includes USB data structures for DFU mode, a pointer to the bdev list structures for the Secure ROM's scheduler, as well as the addresses of the hardware SHA1 registers. All of these are potential avenues for exploitation.
Exploit :-
The goal of the exploit was gain the arbitary code execution capability.
The exploit uses the overflow to overwrite one of the address in SHA1 registers which is the only one responsible for copying the hash code into hardware. Code execution is achieved by specifically by overwriting the LR of the function performing the write to the "SHA1 register"
so that instead of returning to the main SHA1 routine it will return to a chosen location in the memory which contains the payload code. And the location chosen is within the memory filled with the LLB's IMG3, so that payload can be placed with LLB's IMG3.
The challenge is to determine where to put in as the SHA1 register location so that the right portion of stack can be overwritten with the payload LR. This was tough without having access to any sort of exception dump & Apple already disabled the crash register dumps in bootrom. And finally after performing the static analysis of a very detailed IDB and theoretically call stack for both the invocations of SHA1 hardware within the bootrom code, they discovered a way to alter IMG3 DER so that the second invocation of the SHA1 hardware was not performed without affecting the first.
The final SHA1 register address was chosen so the first dword of the DATA tag of the LLB IMG3 would replace sub_5E54's LR. This is because the first dword of the IMG3 that can be altered without changing the IMG3's structure. The LR replacement must be done the first time the exploit is triggered, or else the bootrom will crash. Since sub_5E54 takes first 0x40 bytes of data at a time, the replaced LR should be within 0x40 bytes of data to be hashed. Data be hashed starts at 0xC bytes from the start of IMG3, and the first dword of the DATA tag id 0x20 bytes the start of IMG3. Thus the chosen SHA1 register address was 0x20-0xC = 0x14 bytes before sub_5E54's LR. So it must be 0x2202FE24. Note that the exploit will also be trash up 0x2202FE24 + 0x40 = 0x2202FE64. So the sizable portion of doComputeSHA1's stack will be trashed as well.
So the final exploit IMG3 was a regular IMG3 with padding up to 0x24000 bytes. The next 0x100 bytes were taken from the original initialization values for 0x22024000. However 0x240FC, the offset of SHA1 register address was altered to 0x22023000. Payload code was placed at 0x23000.
Payload :-
Now we know how it will exploit, now what is the payload.
So the goal to the payload was to allow unsigned LLB to be loaded.
There are several ways to do this, one of them was to simply use JumpToMemory function which is designed to prepare SoC and invoke the LLB code. However it is designed to be used on decrypted code and the LLB code is currently resides in the encrypted form within IMG3 DATA tag. The simple solution for this on ewas to simply use Apple's own bootrom machinery to decrypt and execute the code.
Then the final payload was to return past the verification of epoch and other tags in the LLB's IMG3 to a spot right before the DATA tag was loaded from the memory and decrypted. R5 was to set to 0, to ensure decryption would not be skipped. And then the original value of DATA dword is written back to 0x22000020 by the payload , and the original SHA1 register value was written back to 0x2202FE24 to ensure that it will only activate once.
I know this is pretty confusing, I read this thing over and over to understand what's happening.
Hope this will help you in your hacking career. For any queries drop a comment, I'll try my best to clear those.
Thanks