winXP栈溢出漏洞深度学习
一:环境
windowsXP,vc6,ollydbg,ultraedit
二:覆盖邻接变量
原理:利用strcpy函数不会检查长度的漏洞,覆盖临近数组的flag变量,从而绕过验证
先构建一个漏洞程序
因为栈的生长方向是从高地址到低地址的,也就是先声明的变量在高地址,后声明的变量在低地址
栈向下生长,但数组向上溢出,我们的buffer数组预先只定义了44个字节的位置,所以buffr数组溢出的第一个字节就是flag的位置

在vc6里面新建一个空项目,添加一个.c文件
1 | #include <stdio.h> |
编译

在debug文件同层创建一个reg.txt,写入密码12345678,运行看看有没有问题


正常

输入44个’1’,填充44个字节没因为fscanf会自动在末尾加上\0,这个\0会覆盖flag的最低位,把flag从1变成0,表示验证通过了

防御方向:限制复制长度
二:植入shellcode(运行漏洞程序后令win系统弹出弹窗)
user32.dll:win动态链接库,包含messageboxa函数
MessageBoxA:是Windows 系统中弹出提示框的 API 函数。调用它就能显示一个窗口
实现思路:后面的 shellcode 需要直接调用 MessageBoxA,但代码里不能写函数名(因为植入的是机器码),必须知道它在内存中的 入口地址,然后让程序跳转到这个地址去执行。
所以我们先通过这个c代码得到

在 Windows XP 中,user32.dll 的加载基址是 0x77D10000。
MessageBoxA 在 user32.dll 中的偏移是 0x000407EA。
入口地址 = 基址 + 偏移 =0x77D10000 + 0x000407EA = 0x77D507EA
ollydbg打开exe文件,在菜单的试图里面找到调试窗口→watch
在watch窗口里面搜一下&buffer
得到buffer的地址:0x0012faf0

开始构建shellcode,首先,调用MessageBoxA函数,我们需要四个参数:
1hWnd——父窗口句柄指定哪个窗口作为消息框的父窗口,这个实验我们传进去0/NULL,表示这是一个独立的窗口2IpText显示的文本3IpCaption标题栏文字4uType按钮类型,这个实验传0,代表只显示确定按钮
在win中,压栈顺序是从右往左,所以参数顺序是4321,之后就可以调用MessageBoxA
在压到3,2参数部分的时候,要对字符串进行处理,要先把字符串写入栈内存,再把字符串的地址作为参数进行传递
顺序如下:
汇编机器码作用 XOR EBX, EBX 33 DB
EBX = 0 PUSH EBX 53
压入 uType=0(参数4) PUSH 0x74736577 68 77 65 73 74
压入 “west” PUSH 0x74736577 68 77 65 73 74
压入 “west” MOV EAX, ESP 8B C4
EAX = 字符串地址 PUSH EBX 53
压入 hWnd=0(参数1) PUSH EAX 50
压入 lpText(参数2) PUSH EAX 50
压入 lpCaption(参数3) PUSH EBX 53
压入 uType=0(参数4) MOV EAX, 0x77D507EA B8 EA 07 D5 77
函数地址入 EAX CALL EAX FF D0
调用
以上0~25这段机器码就是弹窗部分
26~43内18个字节用90填充,表示NOP指令,什么都不做
44~47内四个字节用90填充,覆盖旧的flag
48~51四个字节用90填充,覆盖旧的EBP栈顶指针
(因为返回地址再flag和EBP后面,要覆盖返回地址,必须先把前52个字节填满,90=NOP(空操作),CPU执行到这里什么都不做,继续往下)
52~55四个字节填充 F0 FA 12 00,表示返回地址→指向buffer[0]
打开UltraEdit,CTRL+G进入十六进制,开始填充机器码

之后保存到debug的同层——reg.txt
再次运行程序,成功跳出弹窗

- 标题: winXP栈溢出漏洞深度学习
- 作者: Lee
- 创建于 : 2026-07-20 02:39:09
- 更新于 : 2026-07-20 02:39:09
- 链接: https://leeei.site/2026/07/20/winXP栈溢出深度学习/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。