需要利用缓冲区溢出。不知道执行漏洞代码后如何恢复堆栈?
基本上我正在利用的函数是这样的:
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 个字和一个用于返回长的字节,我用 0x313131 填充以使其长度为 6 个字。此时,我的漏洞利用字符串长度为 520 字节,这正是缓冲区低于 %ebp 的长度,因此我添加了旧 ebp 的地址和 nopsled 内某处的地址,覆盖 %ebp 处的当前值以及返回值getbufn 的地址。
问题是当程序第二次执行 %ebp 时,其地址 0x10 低于其先前的地址,因此我的未损坏 %ebp 的方法不起作用,并且 main 检测到 0x12345678 不在 -0x10(%ebp) 处。如何恢复 %ebp 的损坏?
Basically the function I am exploiting is this:
int getbufn()
{
char buf[512];
Gets(buf);
return 1;
}
When I run the main program the function executes 5 times and each time the location of buf changes and so does the location of %ebp. What I am supposed to do is place a specific hex value, lets say 0xFFFFFFFF, into a variable and the main program checks each time to see if that variable is there. If it is it executes again until all 5 times are done and the program exits quietly.
The problem I am having is that right before the check for the hex value there is a check for another value that is constant, lets say 0x12345678. If I have corrupted 0x12345678 and it's not there, the program explodes on me.
I have figured out that 0x12345678 is stored in -0x10(%ebp) so I know it is based off %ebp and I know the address of %ebp each time but I can only get the exploit to work the first time. I do this by basically nopsled-ing 496 bytes and the having this machine code in byte format:
mov 0xFFFFFFFF, %eax
movl address old ebp, %ebp
push correct return adress in function main
ret
which ends up being 5 words and a byte for return long which I fill with 0x313131 to make it 6 words long. At this point my exploit string is 520 bytes long which is exactly how much the buffer is below %ebp and so I add on the address of old ebp and an address somewhere inside my nopsled overwriting the current value at %ebp as well as the return address for getbufn.
The problem is when the program executes a 2nd time %ebp is in an address 0x10 lower than its previous address so my way of uncorrupting %ebp doesn't work and main detects that 0x12345678 is not at -0x10(%ebp). How do I uncorrupt %ebp?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
pmjordan 是对的,您应该能够计算 %ebp 相对于 %esp 的位置。请记住,%esp 是当前堆栈指针,%ebp 是前一个函数的堆栈指针所在的位置。您需要一个从 %esp 计算出的动态 %ebp,而不是静态的 %ebp(或者实际上只是查看堆栈变量位于 %esp 偏移量的内存中存储的内容)。伪代码类似于:
pmjordan is right, you should be able to calculate where %ebp is in relation to %esp. Remember, the %esp is your current stack pointer and %ebp is where your stack pointer was for the previous function. Instead of having a static %ebp, you need to have a dynamic one calculated from %esp (or really just looking at what is stored at memory located in %esp offset by the stack variables). The pseudo code would be something like: