从Hacking了解返回地址计算:剥削的艺术

k2fxgqgv  于 2023-05-22  发布在  其他
关注(0)|答案(1)|浏览(112)

该程序显示在类似的线程here中。
假设我的操作系统没有实现ASLR或其他缓冲区溢出保护。
长话短说,作者是从一个父进程派生一个子进程,并将父进程创建的缓冲区传递给子进程,以覆盖子堆栈上的返回地址,从而派生一个shell。到目前为止一切顺利。
我不理解的是,返回地址是在父进程中计算的,即:

ret = (unsigned int) &i - offset; // Set return address

这个返回地址是父进程的堆栈地址,但是子进程有自己的堆栈,即地址空间作者如何得出结论,上面计算的ret将是子堆栈帧上nop-sleds / shell的近似位置,因为这两个堆栈是不同的,不相关?
为了进行实验,我尝试暂时关闭ASLR,使用gdb单独调试这些程序,发现当我在main函数上设置断点时,$ESP总是指向父进程的0xffffd02c和子进程的0xffffd04c

pieyvz9o

pieyvz9o1#

这两个进程的堆栈是不相关的,但它们具有相同的地址(虚拟地址)。操作系统将所有用户进程的堆栈放置在同一地址(如果没有ASLR)。即使一个程序调用了另一个程序。这实际上是一个伟大的调试帮助10年前!
当你知道这一点,你如何确定“神奇的”地址?你可以写一个程序,打印一个堆栈变量的地址,然后把这个“神奇的”地址写在纸上,用它来进行所有的攻击。但更好的是,如果您从自己的程序中调用可利用的程序,那么您的程序中已经有了那个“神奇的地址”。

相关问题