Segfault в "write () ../sysdeps/unix/syscall-template.S:84" - PullRequest
0 голосов
/ 20 июня 2019

Я решаю проблему бинарной эксплуатации, используя ROP. Мой код эксплойта работает теоретически, но в программе происходит сбой SIGSEGV. Вот точное сообщение в gdb:

Program received signal SIGSEGV, Segmentation fault.
0xb6f355bc in write () at ../sysdeps/unix/syscall-template.S:84
84  ../sysdeps/unix/syscall-template.S: No such file or directory.

Я пытался понять вывод disas. Вот и это:

(gdb) disas
Dump of assembler code for function write:
   0xb6f355b0 <+0>: ldr r12, [pc, #96]  ; 0xb6f35618
   0xb6f355b4 <+4>: ldr r12, [pc, r12]
   0xb6f355b8 <+8>: teq r12, #0
=> 0xb6f355bc <+12>:    push    {r7}        ; (str r7, [sp, #-4]!)
   0xb6f355c0 <+16>:    bne 0xb6f355dc <write+44>
   0xb6f355c4 <+20>:    mov r7, #4
   0xb6f355c8 <+24>:    svc 0x00000000
   0xb6f355cc <+28>:    pop {r7}        ; (ldr r7, [sp], #4)
   0xb6f355d0 <+32>:    cmn r0, #4096   ; 0x1000
   0xb6f355d4 <+36>:    bxcc    lr
   0xb6f355d8 <+40>:    b   0xb6e8a7d0 <__syscall_error>
   0xb6f355dc <+44>:    push    {r0, r1, r2, r3, lr}
   0xb6f355e0 <+48>:    bl  0xb6f52758 <__libc_enable_asynccancel>
   0xb6f355e4 <+52>:    mov r12, r0
   0xb6f355e8 <+56>:    pop {r0, r1, r2, r3}
   0xb6f355ec <+60>:    mov r7, #4
   0xb6f355f0 <+64>:    svc 0x00000000
   0xb6f355f4 <+68>:    mov r7, r0
   0xb6f355f8 <+72>:    mov r0, r12
   0xb6f355fc <+76>:    bl  0xb6f52810 <__libc_disable_asynccancel>
   0xb6f35600 <+80>:    mov r0, r7
   0xb6f35604 <+84>:    pop {lr}        ; (ldr lr, [sp], #4)
   0xb6f35608 <+88>:    pop {r7}        ; (ldr r7, [sp], #4)
   0xb6f3560c <+92>:    cmn r0, #4096   ; 0x1000
   0xb6f35610 <+96>:    bxcc    lr
   0xb6f35614 <+100>:   b   0xb6e8a7d0 <__syscall_error>
End of assembler dump.

Из того, что я могу сказать, r7 держит какой-то плохой адрес. Так вот info reg:

(gdb) info reg
r0             0x10790  67472
r1             0x2  2
r2             0x1078e  67470
r3             0xe59f3014   3852414996
r4             0x1078e  67470
r5             0x2  2
r6             0x1042c  66604
r7             0x0  0
r8             0x0  0
r9             0x0  0
r10            0xb6ffd000   3070218240
r11            0xe1a00000   3785359360
r12            0x0  0
sp             0x106fc  0x106fc <write_anywhere+16>
lr             0xb6edbf4c   -1225932980
pc             0xb6f355bc   0xb6f355bc <write+12>
cpsr           0x60000010   1610612752

Для чего бы то ни было, архитектура ARM 32-разрядная, ОС - Debian Stretch (Raspbian), работающая через QEMU.

Выход backtrace:

(gdb) backtrace
#0  0xb6f355bc in write () at ../sysdeps/unix/syscall-template.S:84
#1  0xb6edbf4c in _IO_new_file_write (f=0x1042c <_start>, data=0x2, n=0)
    at fileops.c:1271
#2  0xe28bd000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Выполнение переходит в _IO_new_file_write, который вызывает write, что, в свою очередь, приводит к ошибкам. Вот код:

Dump of assembler code for function _IO_new_file_write:
   0xb6edbf28 <+0>: push    {r4, r5, r6, r7, r8, r9, r10, lr}
   0xb6edbf2c <+4>: subs    r8, r2, #0
   0xb6edbf30 <+8>: mov r6, r0
   0xb6edbf34 <+12>:    ble 0xb6edbfd8 <_IO_new_file_write+176>
   0xb6edbf38 <+16>:    mov r5, r1
   0xb6edbf3c <+20>:    mov r4, r8
   0xb6edbf40 <+24>:    mov r9, #4
   0xb6edbf44 <+28>:    b   0xb6edbf64 <_IO_new_file_write+60>
=> 0xb6edbf48 <+32>:    bl  0xb6f355b0 <write>
   0xb6edbf4c <+36>:    cmp r0, #0
   0xb6edbf50 <+40>:    blt 0xb6edbfa0 <_IO_new_file_write+120>
   0xb6edbf54 <+44>:    sub r4, r4, r0
   0xb6edbf58 <+48>:    cmp r4, #0
   0xb6edbf5c <+52>:    add r5, r5, r0
... snip ...
...