
Windows的SEH(结构化异常处理)和APC(异步过程调用)机制可通过篡改异常处理链或插入异步任务,绕过代码签名验证、内存保护(如DEP/ASLR),执行恶意代码。
老师讲解:SEH是每个线程的异常处理链表,用于处理同步异常(如访问非法内存、断言失败)。当程序发生异常时,系统按链表顺序调用异常处理函数,直到找到处理或终止程序。关键边界:终止异常(如EXCEPTION_STACK_OVERFLOW、EXCEPTION_ACCESS_VIOLATION)不会触发SEH处理,系统直接终止线程。APC是线程内的异步函数队列,允许线程在执行过程中插入后台任务,由线程调度器按优先级执行,前提是线程处于可调度状态(如等待I/O、时间片用完或被阻塞时)。类比:SEH像“异常处理链”,每个节点是异常处理函数;APC像“后台任务列表”,线程可插入任务,在当前任务间隙执行。利用核心:异常处理链或APC函数可被替换为恶意代码,当触发异常或线程调度时执行,绕过安全检查。
| 特性 | SEH(结构化异常处理) | APC(异步过程调用) |
|---|---|---|
| 定义 | 线程级异常处理链表,处理同步异常(如访问违规、断言失败) | 线程内异步函数队列,处理异步任务(如后台执行代码) |
| 触发时机 | 程序发生异常时(如访问非法内存)触发,终止异常(如EXCEPTION_STACK_OVERFLOW)不触发 | 线程调度器按优先级触发(如当前线程执行到等待状态时),需线程处于可调度状态 |
| 核心数据结构 | 每个线程的异常处理链(指向异常处理函数的指针链,首节点为_SEH结构体,包含异常处理函数地址) | 线程的APC队列(异步函数指针链,带优先级,结构为APC_struct,包含函数指针和参数) |
| 使用场景 | 错误处理、调试、安全检查(如代码签名验证时检查SEH完整性) | 异步操作、延迟执行任务、绕过同步检查(如异常处理时执行APC) |
| 注意点 | 异常处理链可被系统检查(如代码签名验证时验证SEH是否被篡改),篡改会触发安全机制(如非法操作提示) | APC函数执行时不受当前线程上下文限制,但需确保线程可调度,否则APC无法执行;APC优先级高于当前任务,可抢占执行 |
假设目标程序有代码签名,攻击者通过构造访问非法内存的异常,替换SEH链表首节点为恶意处理函数,执行恶意代码(绕过DEP与ASLR)。伪代码示例:
// 原程序中的漏洞函数(访问非法内存)
void vulnerable_func() {
int *p = (int *)0xdeadbeef; // 非法内存地址
*p = 1; // 触发访问违规异常(EXCEPTION_ACCESS_VIOLATION)
}
// 攻击者插入的恶意SEH处理函数(绕过DEP与ASLR)
void malicious_handler(EXCEPTION_POINTERS *ep) {
// 1. 绕过DEP:执行非授权代码(加载恶意DLL并执行)
// 2. 绕过ASLR:异常处理时内存地址未被随机化(异常处理时访问的内存地址可预测)
HMODULE h = LoadLibraryA("malicious.dll");
if (h) {
typedef void (*func_type)();
func_type func = (func_type)GetProcAddress(h, "malicious_func");
if (func) func(); // 执行恶意代码(如执行系统命令)
}
}
// 攻击者修改SEH链表(通过漏洞函数触发异常)
__try {
vulnerable_func(); // 触发访问违规异常
} __except (malicious_handler) { // 调用恶意SEH处理函数
// 执行恶意代码,绕过代码签名与内存保护
}
解释:程序访问非法内存触发异常,系统按SEH链表调用恶意处理函数,执行恶意代码(加载恶意DLL),绕过代码签名验证。同时,异常处理时内存地址未被随机化(ASLR未生效),且执行了非授权代码(DEP绕过)。注意:异常处理函数的代码地址在异常处理时不受ASLR影响(因为异常处理是在异常发生时,系统会使用异常处理时的栈地址,而ASLR随机化的是程序加载时的内存地址,异常处理时的栈地址可通过相对地址访问,因此可绕过ASLR)。
“面试官您好,关于Windows安全模块的利用,核心是利用SEH(结构化异常处理)和APC(异步过程调用)机制绕过代码签名和内存保护。SEH是线程的异常处理链表,当程序出错时按顺序调用处理函数,比如访问非法内存触发异常,系统调用SEH链表中的处理函数。APC是线程内的异步函数队列,由线程调度器触发,可以在异常处理时插入后台任务。攻击者通过篡改SEH链表,插入恶意处理函数,当异常发生时执行恶意代码,比如加载恶意DLL。比如,构造访问0xdeadbeef的内存,触发访问违规异常,替换SEH链表首节点为恶意处理函数,执行后加载恶意DLL,绕过代码签名。APC则是在异常处理中插入异步任务,延迟执行,比如在异常处理时调用APC函数,执行恶意代码。具体来说,SEH利用异常处理链的入口,APC利用线程调度时机,两者结合可绕过DEP(执行非授权代码)和ASLR(异常处理时内存地址未被随机化),实现漏洞利用。”