基本上我正在利用的功能是:
int getbufn()
{
char buf[512];
Gets(buf);
return 1;
}
当我运行主程序时,该函数执行5次,每次buf的位置改变,%ebp的位置也改变。我应该做的是将一个特定的十六进制值,比如0xFFFFFFFF,放入一个变量中,主程序每次都会检查该变量是否存在。如果它再次执行,直到完成所有5次并且程序安静地退出。
我遇到的问题是,在检查十六进制值之前,检查另一个值是否为常量,假设为0x12345678。如果我已经损坏了0x12345678并且它不在那里,程序就会爆炸。
我已经发现0x12345678存储在-0x10(%ebp)中,所以我知道它基于%ebp并且我每次都知道%ebp的地址但我只能在第一次使用该漏洞利用。我这样做基本上是用了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不起作用,并且主检测到0x12345678不在-0x10(%ebp) 。我如何解除%ebp的破坏?
答案 0 :(得分:5)
pmjordan是对的,您应该能够计算%ebp相对于%esp的位置。请记住,%esp是您当前的堆栈指针,%ebp是您的堆栈指针用于上一个函数的位置。您需要拥有一个从%esp计算的动态值(或者实际上只是查看存储在%esp偏移量的堆栈变量的内存中),而不是使用静态%ebp。伪代码类似于: