我们有一个程序容易被单字节帧指针覆盖。堆栈被标记为可执行,Linux 机器禁用了 aslr,禁用了堆栈 cookie,并且它是小端标准 x86。
我们可以运行:
buf[256];
for(int i=0; i <=256; i++)
buf[i] = argv[1][i];
但是,我想将我的 shellcode 放入buf
然后跳转到它。如果我使用正常的堆栈溢出,我可以通过转到一个已加载的库来获得利用可靠性,该库在jmp $esp
某处编码了指令,然后将我的 shellcode 放在函数参数所在的位置等等。但这在这里是不可能的。
那么如果它是一个远程进程(你不能硬编码地址值)并且需要利用可靠性,你会怎么做?唯一想到的是堆栈对齐,我们可以预测低位(可能是 2 位还是 3 位?)。
我只需要知道帧指针的低字节,这样我就可以用更小的值控制 eip 覆盖它以指向 jmp esp,并且在 esp 处的指令就像一个短跳转 -0x80 或类似的东西。
我已经减少了帧指针 => ret 被执行 => 控制 eip => 将 eip 指向 jmp esp 指令 => 下一条指令是短跳转 -0xsomevalue 执行 => 有效负载被执行。
我考虑了其他启发式方法,例如将指向 jmp esp 的指针一遍又一遍地写入缓冲区,以便它更有可能控制 eip,但这样我的 jmp -0xsomevalue 方法将不再起作用。