AT+stkprof

From The iPhone Wiki
Revision as of 16:32, 8 January 2009 by Darkmen (talk | contribs) (Unlock task loop)
Jump to: navigation, search

Used as an injection vector for the first iPhone 3G unlock payload.

Credit

geohot

Exploit

There is a stack-based buffer overflow in the at+stkprof command that allows unsigned code execution on the iPhone 3G baseband.

Implementation

The dev team used this exploit in the first public iPhone 3G unlock called yellowsn0w. It can be downloaded from Cydia, and is a daemon that will run in the background. It will inject their payload whenever the baseband is reset.

The source code is also available here [1]

New Implementation (yellowsn0w 0.9.6)

In the newest yellowsn0w, this command is still used as the injection vector for the exploit, but it is used differently. It is still the at+stkprof command, but it seems to send their stuff all in one go.

at+stkprof=122064a541c044b1878222803d0107001320133f8e720470000bf9f1
54000170100546e5640200000005c130100266e5640ddddddddeeeeeeeeb8905120
000000001010101020202020611301000c000000223B22270F32101C1743BAA
50BA40E78213501D00C297810B47A847A8786146C046C046C046C0701118C
93201340246C0E7EF370146C03030473829411+09pG79pG024803A10131016
01FBD00004C711140F0B51C4B80268BB03601188008911A4C301CA0470025
09909820A047071CC56080204000A047802214495200144B041C9847099B01
93442303930A23013405930C23221C06930F49009502960495381C00230D4C
A047021C002804D10B4908980B4B984703E00B490898094B98470BB0F0BD00
0044B33B40AC201420641A0100A0583C20481A010040B53F20541A010000DD
4620581A01006465767465616D31000000004F4B21004552524F52202564000
0000030B5114D85B0114B281C6946FF229847009B0D2B11D101990D4B0A68
1A6004334A681A608A680B4B13600B4B53600B4B93600123CB602023009328
1C6946FF22074B9847DFE700005427234098591620BC792F4000FF000101040
2040304040468D53E207878220

Anyone with a better insight feel free to comment / modify, as I didn't look any further into this, I just looked at the ztringz :)

yellowsn0w 0.9.6 with comments

The exploit consists from 3 parts:

Code loader

ROM:00000000 ; =============== S U B R O U T I N E =======================================
ROM:00000000
ROM:00000000
ROM:00000000 loader
ROM:00000000                 LDR     R2, =0x11700    ; unused ram to place code
ROM:00000002                 ADDS    R4, R2, #1      ; thumb switch
ROM:00000004                 LDR     R3, =0x40159FBF ; at-handler buffer where StrToHex result of the at-command is
ROM:00000006
ROM:00000006 copy.loop                               ; CODE XREF: loader+12�j
ROM:00000006                 LDRB    R0, [R3]        ; copying code until double quotes
ROM:00000008                 CMP     R0, #0x22 ; '"'
ROM:0000000A                 BEQ     run             ; jump thumb code
ROM:0000000C                 STRB    R0, [R2]
ROM:0000000E                 ADDS    R2, #1
ROM:00000010                 ADDS    R3, #1
ROM:00000012                 B       copy.loop       ; copying code until double quotes
ROM:00000014 ; ---------------------------------------------------------------------------
ROM:00000014
ROM:00000014 run                                     ; CODE XREF: loader+A�j
ROM:00000014                 BX      R4              ; jump thumb code
ROM:00000014 ; End of function loader
ROM:00000014
ROM:00000014 ; ---------------------------------------------------------------------------

Task creator

RAM:000119A0 ; =============== S U B R O U T I N E =======================================
RAM:000119A0
RAM:000119A0
RAM:000119A0 handler_replace
RAM:000119A0                 LDR     R0, =0x4011714C ; soft reset handler addr
RAM:000119A2                 ADR     R1, new_handler
RAM:000119A4                 ADDS    R1, #1          ; thumbing
RAM:000119A6                 STR     R1, [R0]        ; setting new handler
RAM:000119A8                 POP     {R0-R4,PC}      ; safe exit fixing stack
RAM:000119A8 ; End of function handler_replace

RAM:000119B0 ; =============== S U B R O U T I N E =======================================
RAM:000119B0
RAM:000119B0
RAM:000119B0 new_handler                             ; DATA XREF: handler_replace+2�o
RAM:000119B0                 PUSH    {R4-R7,LR}
RAM:000119B2                 LDR     R3, =0x403BB344 ; jamptable var
RAM:000119B4                 MOVS    R6, #0x80
RAM:000119B6                 SUB     SP, SP, #0x2C
RAM:000119B8                 LSLS    R6, R6, #4      ; 0x200
RAM:000119BA                 STRH    R0, [R3]        ; saving R0 to mem var
RAM:000119BC                 STR     R1, [SP,#0x40+resp_string] ; saving responce prt to stack
RAM:000119BE                 LDR     R4, =0x201420AC ; malloc
RAM:000119C0                 ADDS    R0, R6, #0
RAM:000119C2                 BLX     R4              ; malloc(0x200)
RAM:000119C4                 MOVS    R5, #0
RAM:000119C6                 STR     R0, [SP,#0x40+ptr_200] ; saving pointer to stack
RAM:000119C8                 MOVS    R0, #0x98       ; sizeof(NU_TASK)
RAM:000119CA                 BLX     R4              ; malloc(0x98)
RAM:000119CC                 ADDS    R7, R0, #0      ; R7 = task
RAM:000119CE                 STR     R5, [R0,#0xC]   ; task.field=0
RAM:000119D0                 MOVS    R0, 0x100
RAM:000119D4                 BLX     R4              ; malloc(0x100)
RAM:000119D6                 MOVS    R2, #0x80
RAM:000119D8                 LDR     R1, =task_loop  ; src
RAM:000119DA                 LSLS    R2, R2, #1      ; size to copy
RAM:000119DC                 LDR     R3, =0x203C58A0 ; bytecpy
RAM:000119DE                 ADDS    R4, R0, #0      ; R4 = dyn_task_loop
RAM:000119E0                 BLX     R3              ; bytecpy(task_loop, dyn_task_loop, 0x100)
RAM:000119E2                 LDR     R3, [SP,#0x40+ptr_200]
RAM:000119E4                 STR     R3, [SP,#4]     ; void *stack_address = malloc(0x200)
RAM:000119E6                 MOVS    R3, #0x44
RAM:000119E8                 STR     R3, [SP,#0xC]   ; priority = 0x44
RAM:000119EA                 MOVS    R3, #0xA
RAM:000119EC                 ADDS    R4, #1          ; thumbing dyn_task_loop
RAM:000119EE                 STR     R3, [SP,#0x14]  ; preempt = NU_PREEMPT
RAM:000119F0                 MOVS    R3, #0xC
RAM:000119F2                 ADDS    R2, R4, #0      ; void(*task_entry)
RAM:000119F4                 STR     R3, [SP,#0x18]  ; auto_start = NU_START
RAM:000119F6                 LDR     R1, =devteam1   ; char *name
RAM:000119F8                 STR     R5, [SP]        ; void *argv = 0
RAM:000119FA                 STR     R6, [SP,#8]     ; stack_size = 0x200
RAM:000119FC                 STR     R5, [SP,#0x10]  ; time_slice = 0
RAM:000119FE                 ADDS    R0, R7, #0      ; NU_TASK *task
RAM:00011A00                 MOVS    R3, #0          ; int argc = 0
RAM:00011A02                 LDR     R4, =0x203FB540 ; NU_Create_Task
RAM:00011A04                 BLX     R4              ; status = NU_Create_Task()
RAM:00011A06                 ADDS    R2, R0, #0
RAM:00011A08                 CMP     R0, #0          ; success = zero
RAM:00011A0A                 BNE     status_error
RAM:00011A0C                 LDR     R1, =OK
RAM:00011A0E                 LDR     R0, [SP,#0x40+resp_string]
RAM:00011A10                 LDR     R3, =0x2046DD00 ; sprintf
RAM:00011A12                 BLX     R3              ; sprintf(resp_string,"OK")
RAM:00011A14                 B       exit            ; fixing stack
RAM:00011A16 ; ---------------------------------------------------------------------------
RAM:00011A16
RAM:00011A16 status_error                            ; CODE XREF: new_handler+5A�j
RAM:00011A16                 LDR     R1, =ERROR
RAM:00011A18                 LDR     R0, [SP,#0x40+resp_string]
RAM:00011A1A                 LDR     R3, =0x2046DD00 ; sprintf
RAM:00011A1C                 BLX     R3              ; sprintf(resp_string,"ERROR")
RAM:00011A1E
RAM:00011A1E exit                                    ; CODE XREF: new_handler+64�j
RAM:00011A1E                 ADD     SP, SP, #0x2C   ; fixing stack
RAM:00011A20                 POP     {R4-R7,PC}      ; bye
RAM:00011A20 ; End of function new_handler
RAM:00011A20
RAM:00011A20 ; ---------------------------------------------------------------------------

Unlock task loop

RAM:00011A64 ; =============== S U B R O U T I N E =======================================
RAM:00011A64
RAM:00011A64 task_loop                               ; DATA XREF: RAM:off_11A2C�o
RAM:00011A64                 PUSH    {R4,R5,LR}
RAM:00011A66                 LDR     R5, =0x40232754 ; sec mailbox
RAM:00011A68                 SUB     SP, SP, #0x14
RAM:00011A6A
RAM:00011A6A loop                                    ; CODE XREF: task_loop+44�j
RAM:00011A6A                 LDR     R3, =0x20165998 ; NU_Receive_From_Mailbox
RAM:00011A6C                 ADDS    R0, R5, #0      ; NU_MAILBOX *mailbox
RAM:00011A6E                 MOV     R1, SP          ; void *Message
RAM:00011A70                 MOVS    R2, #0xFF       ; Timeout
RAM:00011A72                 BLX     R3              ; NU_Receive_From_Mailbox(sec_mailbox,SP,0xFF)
RAM:00011A74                 LDR     R3, [SP]        ; Message[0]
RAM:00011A76                 CMP     R3, #0xD        ; Message[0] = 0xD ?
RAM:00011A78                 BNE     skip            ; 
RAM:00011A7A                 LDR     R1, [SP,#4]     ; Message[1]
RAM:00011A7C                 LDR     R3, =0x402F79BC
RAM:00011A7E                 LDR     R2, [R1]        ; Message[1].field0
RAM:00011A80                 STR     R2, [R3]        ; sec_task_var1 = Message[1].field0
RAM:00011A82                 ADDS    R3, #4          ; 0x402F79C0
RAM:00011A84                 LDR     R2, [R1,#4]     ; Message[1].field1
RAM:00011A86                 STR     R2, [R3]        ; sec_task_var2 = Message[1].field1
RAM:00011A88                 LDR     R2, [R1,#8]     ; Message[1].field2
RAM:00011A8A                 LDR     R3, =0x100FF00
RAM:00011A8C                 STR     R3, [R2]        ; Message[1].field2[0] = 0x100FF00
RAM:00011A8E                 LDR     R3, =0x4020401
RAM:00011A90                 STR     R3, [R2,#4]     ; Message[1].field2[1] = 0x4020401
RAM:00011A92                 LDR     R3, =0x4040403
RAM:00011A94                 STR     R3, [R2,#8]     ; Message[1].field2[2] = 0x4040403
RAM:00011A96                 MOVS    R3, #1
RAM:00011A98                 STR     R3, [R1,#0xC]   ; Message[1].field3 = 1
RAM:00011A9A                 MOVS    R3, #0x20       
RAM:00011A9C                 STR     R3, [SP]        ; Message[0] = 0x20
RAM:00011A9E
RAM:00011A9E skip                                    ; CODE XREF: task_loop+14�j
RAM:00011A9E                 ADDS    R0, R5, #0      ; sec mailbox
RAM:00011AA0                 MOV     R1, SP          ; void *Message
RAM:00011AA2                 MOVS    R2, #0xFF       ; timeout
RAM:00011AA4                 LDR     R3, =0x203ED568
RAM:00011AA6                 BLX     R3              ; NU_Send_To_Mailbox()
RAM:00011AA8                 B       loop            ; NU_Receive_From_Mailbox
RAM:00011AA8 ; End of function task_loop