图解利用SEH过GS思路研究
字数 1953 2025-08-15 21:31:19
利用SEH绕过GS保护的技术研究
一、前言
GS保护(Buffer Security Check)是微软提供的一种栈溢出保护机制,通过在函数调用时插入安全cookie来检测缓冲区溢出。本文介绍一种利用Windows结构化异常处理(SEH)机制绕过GS保护的技术。
二、SEH基础
1. SEH概述
SEH(Structure Exception Handler)是Windows异常处理机制中的重要数据结构,全称为结构化异常处理。每个SEH结构体包含两个DWORD指针:
- SEH链表指针(next seh):指向下一个SEH结构体
- 异常处理函数句柄(Exception handler):指向异常处理函数
2. SEH结构
SEH结构体在栈中的布局:
+-------------------+
| Next SEH指针 | (4字节)
+-------------------+
| 异常处理函数地址 | (4字节)
+-------------------+
3. 攻击原理
由于SEH结构体存放在栈中,通过精心构造的溢出数据可以覆盖SEH结构,将异常处理函数地址修改为攻击者控制的地址,从而实现代码执行。
三、实验环境配置
1. 系统要求
- 操作系统:Windows 7
- 编译器:Visual Studio 2015
2. 编译选项设置
- 修改代码基址:如修改为0x41400000,避免strcpy存在00截断
- 启用GS保护:项目属性→C/C++→代码生成→安全检查→启用安全检查(GS)
- 关闭其他保护:
- 关闭DEP:项目→属性→链接器→高级→数据执行保护(DEP)→否
- 关闭ASLR:项目→属性→链接器→高级→随机基址→否
- 关闭SafeSEH:项目→属性→链接器→高级→映像具有安全异常处理程序→否
3. 构建版本
- 使用Release版本进行编译
四、漏洞代码分析
1. 示例代码
#include "stdafx.h"
#include <windows.h>
#pragma warning(disable:4996)
char payload[] = "..."; // 构造的payload
void test(char* input) {
char buf[200];
strcpy(buf, input); // 典型的栈溢出漏洞
}
int main() {
printf("the code begin!\n");
test(payload);
getchar();
printf("the code end!\n");
return 0;
}
2. 关键点
test()函数中的strcpy()存在典型的栈溢出漏洞- 当
buf变量内容过长时,会破坏堆栈结构并引发SEH异常
五、攻击思路
1. 地址分析
- 局部变量
buf首地址:0x0018fe64 - SEH链地址:0x0018FF78
- 偏移量计算:0x0018FF78 - 0x0018fe64 = 276字节
2. 攻击方法选择
- 直接跳转:将SE handler改为shellcode首地址
- 缺点:需要关闭ASLR,否则地址会变化
- 跳板技术:使用PPT指令序列或jmp esp等实现动态跳转
- 优点:不受ASLR影响
- 本文采用此方法
3. 跳转流程
- 一跳:通过溢出覆盖SE handler,使其指向PPT指令序列地址
- 二跳:PPT指令序列执行pop两次后ret,使EIP指向Next SEH
- 三跳:Next SEH处放置短跳转指令,跳转到shellcode
六、Payload构造
1. Payload结构
+---------------------+
| NOP滑轨 (276字节) |
+---------------------+
| Next SEH覆盖 | (4字节) "\x06\xeb\x06\x90"
+---------------------+
| SE handler覆盖 | (4字节) PPT指令序列地址
+---------------------+
| 8字节NOP滑轨 |
+---------------------+
| Shellcode |
+---------------------+
| 破坏堆栈的填充 | (200字节"a")
+---------------------+
2. 关键部分说明
- Next SEH覆盖:
"\x06\xeb\x06\x90"EB 06:短跳转指令,跳转到当前位置+8处- 添加
\x06\x90确保从前后解析都正确
- SE handler覆盖:PPT指令序列地址(如0x41401370)
- 使用
!mona seh命令查找合适的PPT指令序列
- 使用
- Shellcode:放置在8字节NOP滑轨之后
七、调试过程
1. 关键断点设置
- PPT指令序列地址:0x41401370
- Next SEH地址:0x0018FF78
- SE handler地址:0x0018FF7C
2. 执行流程
strcpy()执行时发生溢出,破坏堆栈结构- 触发异常,系统调用被覆盖的SE handler(PPT指令序列地址)
- 执行PPT指令序列(pop ecx; pop ecx; ret)
- 弹出两个参数后,ret使EIP指向Next SEH
- 执行Next SEH处的跳转指令(EB 06),跳转到shellcode
- 执行shellcode完成攻击
八、技术要点总结
- GS保护绕过核心:在验证security cookie前进行劫持
- SEH利用关键:
- 精确计算偏移量,覆盖SEH结构
- 使用跳板技术实现动态跳转
- 合理构造Next SEH和SE handler的覆盖值
- 环境要求:
- 需要关闭DEP、ASLR和SafeSEH
- 需要精确控制内存布局
九、防御措施
- 启用所有保护机制(DEP、ASLR、SafeSEH)
- 使用更安全的字符串函数(如
strncpy_s) - 进行严格的输入验证
- 使用最新的编译器和安全补丁
十、参考资料
- 《0day安全:软件漏洞分析技术》
- Microsoft文档:Structured Exception Handling
- Mona.py工具文档
这篇文档详细介绍了利用SEH绕过GS保护的技术原理、实现方法和调试过程,涵盖了从环境配置到实际攻击的所有关键步骤。如需进一步了解某些细节,可以参考列出的参考资料或进行更深入的研究。