需要利用缓冲区溢出漏洞,但在执行利用代码后无法弄清楚如何修复堆栈的损坏?

10

我要利用的函数基本上是这样的:

int getbufn()
{
     char buf[512];
     Gets(buf);
     return 1;
}
当我运行主程序时,该函数会执行5次,每次buf的位置和%ebp的位置都会改变。我的任务是将一个特定的十六进制值,比如0xFFFFFFFF,放入一个变量中,然后主程序每次都会检查那个变量是否存在。如果存在,它会再次执行,直到所有5次都完成并且程序安静地退出。
我的问题在于,在检查十六进制值之前,还要检查另一个常数值,比如0x12345678。如果我已经破坏了0x12345678并且它不存在,程序就会崩溃。
我已经知道0x12345678存储在-0x10(%ebp)中,所以我知道它基于%ebp并且每次都知道%ebp的地址,但是我只能使利用代码第一次工作。我通过nopsled-ing 496个字节,并在其中包含这个字节格式的机器代码来做到这一点:
mov  0xFFFFFFFF, %eax
movl address old ebp, %ebp
push correct return adress in function main
ret
这段代码最终会变成5个单词和一个返回long类型的字节,我使用0x313131填充它使其长度为6个单词。此时我的攻击字符串长达520字节,刚好是%ebp下面的缓冲区大小,因此我加上旧ebp地址以及nopsled中某个地址的值,覆盖了%ebp的当前值以及getbufn函数的返回地址。
问题在于当程序第二次执行时,%ebp的地址比先前的地址低了0x10,因此我的解除错误%ebp的方式无效,main函数检测到0x12345678不在-0x10(%ebp)处。如何修复%ebp的错误?

1
你能不能不将%ebp计算为相对于%esp的偏移量呢?也就是说,恢复%ebp时不使用立即地址的movl,而是将%esp复制到%ebp中,并在其上添加偏移量? - pmdj
你使用了哪些编译器标志,用的是哪个编译器?能提供完整的程序和漏洞代码吗? - Stellarator
3
一所学校布置缓冲区漏洞作业... 令人敬佩! - Sedat Kapanoglu
1个回答

5

pmjordan说得对,你应该能够计算%ebp相对于%esp的位置。请记住,%esp是你当前的堆栈指针,而%ebp是前一个函数的堆栈指针。你需要有一个动态的%ebp,从%esp中计算(或者只看存储在%esp偏移量中的内存存储器)。伪代码如下:

  1. 计算%ebp相对于%esp的偏移量
  2. 读取存储在该内存位置的值,并为自己存储
  3. 进行你的攻击
  4. 恢复步骤2中存储的旧%ebp值
  5. 返回

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接