图解利用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. 编译选项设置

  1. 修改代码基址:如修改为0x41400000,避免strcpy存在00截断
  2. 启用GS保护:项目属性→C/C++→代码生成→安全检查→启用安全检查(GS)
  3. 关闭其他保护
    • 关闭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. 攻击方法选择

  1. 直接跳转:将SE handler改为shellcode首地址
    • 缺点:需要关闭ASLR,否则地址会变化
  2. 跳板技术:使用PPT指令序列或jmp esp等实现动态跳转
    • 优点:不受ASLR影响
    • 本文采用此方法

3. 跳转流程

  1. 一跳:通过溢出覆盖SE handler,使其指向PPT指令序列地址
  2. 二跳:PPT指令序列执行pop两次后ret,使EIP指向Next SEH
  3. 三跳: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. 关键部分说明

  1. Next SEH覆盖"\x06\xeb\x06\x90"
    • EB 06:短跳转指令,跳转到当前位置+8处
    • 添加\x06\x90确保从前后解析都正确
  2. SE handler覆盖:PPT指令序列地址(如0x41401370)
    • 使用!mona seh命令查找合适的PPT指令序列
  3. Shellcode:放置在8字节NOP滑轨之后

七、调试过程

1. 关键断点设置

  • PPT指令序列地址:0x41401370
  • Next SEH地址:0x0018FF78
  • SE handler地址:0x0018FF7C

2. 执行流程

  1. strcpy()执行时发生溢出,破坏堆栈结构
  2. 触发异常,系统调用被覆盖的SE handler(PPT指令序列地址)
  3. 执行PPT指令序列(pop ecx; pop ecx; ret)
    • 弹出两个参数后,ret使EIP指向Next SEH
  4. 执行Next SEH处的跳转指令(EB 06),跳转到shellcode
  5. 执行shellcode完成攻击

八、技术要点总结

  1. GS保护绕过核心:在验证security cookie前进行劫持
  2. SEH利用关键
    • 精确计算偏移量,覆盖SEH结构
    • 使用跳板技术实现动态跳转
    • 合理构造Next SEH和SE handler的覆盖值
  3. 环境要求
    • 需要关闭DEP、ASLR和SafeSEH
    • 需要精确控制内存布局

九、防御措施

  1. 启用所有保护机制(DEP、ASLR、SafeSEH)
  2. 使用更安全的字符串函数(如strncpy_s
  3. 进行严格的输入验证
  4. 使用最新的编译器和安全补丁

十、参考资料

  1. 《0day安全:软件漏洞分析技术》
  2. Microsoft文档:Structured Exception Handling
  3. Mona.py工具文档

这篇文档详细介绍了利用SEH绕过GS保护的技术原理、实现方法和调试过程,涵盖了从环境配置到实际攻击的所有关键步骤。如需进一步了解某些细节,可以参考列出的参考资料或进行更深入的研究。

利用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结构体在栈中的布局: 3. 攻击原理 由于SEH结构体存放在栈中,通过精心构造的溢出数据可以覆盖SEH结构,将异常处理函数地址修改为攻击者控制的地址,从而实现代码执行。 三、实验环境配置 1. 系统要求 操作系统:Windows 7 编译器:Visual Studio 2015 2. 编译选项设置 修改代码基址 :如修改为0x41400000,避免strcpy存在00截断 启用GS保护 :项目属性→C/C++→代码生成→安全检查→启用安全检查(GS) 关闭其他保护 : 关闭DEP:项目→属性→链接器→高级→数据执行保护(DEP)→否 关闭ASLR:项目→属性→链接器→高级→随机基址→否 关闭SafeSEH:项目→属性→链接器→高级→映像具有安全异常处理程序→否 3. 构建版本 使用Release版本进行编译 四、漏洞代码分析 1. 示例代码 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结构 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保护的技术原理、实现方法和调试过程,涵盖了从环境配置到实际攻击的所有关键步骤。如需进一步了解某些细节,可以参考列出的参考资料或进行更深入的研究。