返回地址不必指向同一缓冲区中的代码,这样做通常更容易。如果您可以将 shell 代码和返回地址放入同一个缓冲区,那么这是最简单的。如果可以溢出的缓冲区太小而无法容纳 shell 代码,则可以将 shell 代码放入另一个缓冲区,然后在易受攻击的缓冲区溢出时跳转到该缓冲区。
此外,数据执行保护或 (NX) 等保护措施可防止从堆栈执行代码。在这种情况下,可以使用诸如面向返回的编程之类的技术来规避 DEP。该技术涉及使用合法的可执行代码段来运行攻击者想要的代码。
这可能很棘手,可能需要对有效负载进行一些摆弄。 通常缓冲区的开头是word
对齐的地址。在这种情况下,确保返回地址正确对齐意味着写入一个倍数 CPU 字的缓冲区(32 位机器为 4 个字节,64 位机器为 8 个字节)。如果缓冲区不是字对齐的,那么攻击者可能只是通过一次添加或删除字节来进行试验,直到他认为它是。
在一个缓冲区中做所有事情更简单的原因是,在注入 shell 代码和跳转到新修改的返回地址之间不会有太大变化。在攻击点,攻击者不太可能引用另一个进程的内存,因此我们必须查看进程中的缓冲区。
将 shell 代码放入不同的缓冲区需要攻击者了解缓冲区将保留多长时间。不同的函数调用是否会导致其中一个缓冲区被释放?是堆上的缓冲区之一而不是堆栈上的缓冲区吗?只要您的单个缓冲区足够大,将 NOP sled 和 shell 代码放在开头附近,然后用返回地址填充其余部分就简单多了。与查找一个缓冲区以填充 shell 代码和另一个缓冲区以填充前一个缓冲区的地址相比。一些 shell 代码也可能引用堆栈指针,这意味着它需要正确设置。