The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Difference between revisions of "Usb control msg(0x21, 2) Exploit"
ChronicDev (talk | contribs) (→Credit (Alphabetical)) |
m |
||
(28 intermediate revisions by 11 users not shown) | |||
Line 1: | Line 1: | ||
{{DISPLAYTITLE:usb_control_msg(0x21, 2) Exploit}} |
{{DISPLAYTITLE:usb_control_msg(0x21, 2) Exploit}} |
||
+ | A null pointer dereference vulnerability exists in the versions of [[iBoot]]/[[iBSS]]/[[iBEC]] found in firmwares 3.1/3.1.1 and 3.1.2 (and presumably everything before) on all iDevices. It was fixed in [[iBoot-636.66.33]], which was included with 3.1.3. [[N88AP|iPhone 3GS]] ([[Bootrom 359.3.2|new bootrom]]) and [[N18AP|iPod touch (3rd generation)]] owners who saved their [[SHSH]] for the aforementioned firmwares, and [[N72AP|iPod touch (2nd generation)]] ([[Bootrom 240.5.1|new bootrom]]) owners could have used it for a [[tethered jailbreak]] on 4.0 and 4.1, until [[Limera1n]] was released. |
||
+ | |||
== Credit (Alphabetical) == |
== Credit (Alphabetical) == |
||
− | * '''vulnerability''': pod2g and westbaer, also discovered independently by gray, also discovered independently by [[geohot]] |
+ | * '''vulnerability''': [[User:Pod2g|pod2g]] and [[westbaer]], also discovered independently by [[gray]], also discovered independently by [[User:geohot|geohot]] |
− | * '''exploitation''': ius, chronic, pod2g, and posixninja |
+ | * '''exploitation''': [[ius]], [[User:ChronicDev|chronic]], [[User:Pod2g|pod2g]], and [[User:posixninja|posixninja]], also [[User:geohot|geohot]] |
− | * '''payload ([[ |
+ | * '''payload''': [[User:geohot|geohot]] ([[blackra1n]]), [[User:ChronicDev|chronic]] and [[User:posixninja|posixninja]] ([[Greenpois0n (jailbreak)|greenpois0n]]) |
== Vulnerability == |
== Vulnerability == |
||
− | '''pod2g''' and '''westbaer''' discovered, via some reversing + fuzzing, you could overwrite the content of 0x0 thanks to Apple not checking the contents of a register they should have, shown in the disassm below. |
+ | '''[[User:Pod2g|pod2g]]''' and '''[[westbaer]]''' discovered, via some reversing + fuzzing, you could overwrite the content of 0x0 thanks to Apple not checking the contents of a register they should have, shown in the disassm below. This can be exploited because MMU maps whatever is running ([[LLB]], [[iBoot]], etc.) to 0x0 so that if an exception vector is triggered, it would jump to the one designed to be used with what is running, versus jumping to what is normally located at 0x0, the [[S5L8920|bootrom]]. |
All you need to do is send the following (assuming you're using libusb 0.1.x)... |
All you need to do is send the following (assuming you're using libusb 0.1.x)... |
||
Line 13: | Line 15: | ||
memcpy(0, LOAD_ADDR, 0x2000); |
memcpy(0, LOAD_ADDR, 0x2000); |
||
− | As you can see, we have full control over the first 0x2000 bytes of iBoot. |
+ | As you can see, we now have full control over the first 0x2000 bytes of iBoot. |
=== Disassm === |
=== Disassm === |
||
Line 37: | Line 39: | ||
== Exploitation == |
== Exploitation == |
||
− | + | By using a [http://www.juniper.net/solutions/literature/white_papers/Vector-Rewrite-Attack.pdf vector rewrite attack], it's possible to replace the address of the irq vector handler (0x38) within a 0x2000 [[iBoot]] chunk that we send, with the location of the payload to be executed. Although, since we are hijacking the irq exception vector, you must disable interrupts first. Here is the basic procedure: |
|
* Call enter_critical_task(); disabling interrupts, so that your code can reliably execute. |
* Call enter_critical_task(); disabling interrupts, so that your code can reliably execute. |
||
− | * Restore 0x38 with the original irq vector address |
+ | * Restore 0x38 (irq handler) with the original irq vector address |
* '''DO WHAT YOU WANT AT THIS POINT, YOU MAY NOT USE INTERRUPTS'''. |
* '''DO WHAT YOU WANT AT THIS POINT, YOU MAY NOT USE INTERRUPTS'''. |
||
* Call exit_critical_task(); re-enabling interrupts. |
* Call exit_critical_task(); re-enabling interrupts. |
||
Line 45: | Line 47: | ||
=== Roadblocks === |
=== Roadblocks === |
||
+ | If what you send is not 0x2000 bytes, the remainder is filled in with zeroes, which is bad. Due to this, you need to restore the first 0x2000 of iBoot before your payload returns execution to [[iBoot]]. Also you must disable interrupts, to prevent iBoot from calling the irq vector while your payload is being executed. Because of this, it rules out the possibility of reading the 0x2000 iBoot chunk needed from [[NOR]], from within iBoot itself, since nor_read(); requires interrupts. |
||
− | * If what you send is not 0x2000 bytes, the remainder is filled in with zeroes, which is bad. |
||
+ | |||
− | * Due to the above rule, you need the first 0x2000 of a decrypted iBoot by the time your payload is done running. |
||
+ | One way to get around the need of sending the 0x2000 [[iBoot]] chunk is to hook the image_load(); function in the [[LLB]] which is sitting intact in memory. This was successfully done in [[blackra1n]]. |
||
− | * You must disable interrupts to reliably execute your payload. Due to this, this will rule out the possibility of reading the 0x2000 iBoot chunk needed from NOR, since nor_read(); requires interrupts. |
||
The [[PwnageTool]] method requires an [[IPSW]] to be input in order to create a custom firmware anyway, so the 0x2000 chunk is not an issue. It can just be copied from the [[iBoot]] in the [[IPSW]]. |
The [[PwnageTool]] method requires an [[IPSW]] to be input in order to create a custom firmware anyway, so the 0x2000 chunk is not an issue. It can just be copied from the [[iBoot]] in the [[IPSW]]. |
||
+ | |||
+ | === Implementation === |
||
+ | * [[blackra1n]] |
||
+ | * [[redsn0w]] |
||
+ | |||
+ | [[Category:Exploits]] |
||
+ | [[Category:iBoot Exploits]] |
Latest revision as of 16:17, 22 May 2022
A null pointer dereference vulnerability exists in the versions of iBoot/iBSS/iBEC found in firmwares 3.1/3.1.1 and 3.1.2 (and presumably everything before) on all iDevices. It was fixed in iBoot-636.66.33, which was included with 3.1.3. iPhone 3GS (new bootrom) and iPod touch (3rd generation) owners who saved their SHSH for the aforementioned firmwares, and iPod touch (2nd generation) (new bootrom) owners could have used it for a tethered jailbreak on 4.0 and 4.1, until Limera1n was released.
Contents
Credit (Alphabetical)
- vulnerability: pod2g and westbaer, also discovered independently by gray, also discovered independently by geohot
- exploitation: ius, chronic, pod2g, and posixninja, also geohot
- payload: geohot (blackra1n), chronic and posixninja (greenpois0n)
Vulnerability
pod2g and westbaer discovered, via some reversing + fuzzing, you could overwrite the content of 0x0 thanks to Apple not checking the contents of a register they should have, shown in the disassm below. This can be exploited because MMU maps whatever is running (LLB, iBoot, etc.) to 0x0 so that if an exception vector is triggered, it would jump to the one designed to be used with what is running, versus jumping to what is normally located at 0x0, the bootrom.
All you need to do is send the following (assuming you're using libusb 0.1.x)...
usb_control_msg(iDev, 0x21, 2, 0, 0, 0, 0, 1000);
And thanks to our vulnerability, it will do this:
memcpy(0, LOAD_ADDR, 0x2000);
As you can see, we now have full control over the first 0x2000 bytes of iBoot.
Disassm
// R5: a pointer to a buffer is here if requesttype==0xA1. // however, if requesttype==0x21, R5 is undefined. SRAM:22009ED2 code_1 ; CODE XREF: handle_file_io_control_req+62�j SRAM:22009ED2 014 36 49 LDR R1, =usb_file_loadaddr SRAM:22009ED4 014 36 4B LDR R3, =usb_file_offset SRAM:22009ED6 014 28 68 LDR R0, [R5] SRAM:22009ED8 014 09 68 LDR R1, [R1] SRAM:22009EDA 014 1B 68 LDR R3, [R3] SRAM:22009EDC 014 22 1C ADDS R2, R4, #0 SRAM:22009EDE 014 C9 18 ADDS R1, R1, R3 SRAM:22009EE0 014 07 F0 94 EF BLX memcpy SRAM:22009EE4 014 00 2E CMP R6, #0 SRAM:22009EE6 014 53 D0 BEQ return SRAM:22009EE8 014 01 23 MOVS R3, #1 SRAM:22009EEA 014 33 60 STR R3, [R6] SRAM:22009EEC 014 50 E0 B return
Exploitation
By using a vector rewrite attack, it's possible to replace the address of the irq vector handler (0x38) within a 0x2000 iBoot chunk that we send, with the location of the payload to be executed. Although, since we are hijacking the irq exception vector, you must disable interrupts first. Here is the basic procedure:
- Call enter_critical_task(); disabling interrupts, so that your code can reliably execute.
- Restore 0x38 (irq handler) with the original irq vector address
- DO WHAT YOU WANT AT THIS POINT, YOU MAY NOT USE INTERRUPTS.
- Call exit_critical_task(); re-enabling interrupts.
- Call the irq handler so that the interrupt request that you hijacked can execute.
Roadblocks
If what you send is not 0x2000 bytes, the remainder is filled in with zeroes, which is bad. Due to this, you need to restore the first 0x2000 of iBoot before your payload returns execution to iBoot. Also you must disable interrupts, to prevent iBoot from calling the irq vector while your payload is being executed. Because of this, it rules out the possibility of reading the 0x2000 iBoot chunk needed from NOR, from within iBoot itself, since nor_read(); requires interrupts.
One way to get around the need of sending the 0x2000 iBoot chunk is to hook the image_load(); function in the LLB which is sitting intact in memory. This was successfully done in blackra1n.
The PwnageTool method requires an IPSW to be input in order to create a custom firmware anyway, so the 0x2000 chunk is not an issue. It can just be copied from the iBoot in the IPSW.