51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

请解释Windows结构化异常处理(SEH)的工作原理,并说明如何利用SEH机制进行漏洞攻击(如缓冲区溢出后跳转到异常处理函数),以及常见的防御措施有哪些?

360安全研究员(Windows方向)难度:中等

答案

1) 【一句话结论】Windows结构化异常处理(SEH)通过异常处理链表捕获程序异常,攻击者可利用缓冲区溢出覆盖异常处理函数指针,跳转执行恶意代码;常见防御措施包括数据执行保护(DEP)、地址空间布局随机化(ASLR)等。

2) 【原理/概念讲解】SEH是Windows内核提供的异常处理机制,用于捕获程序运行时发生的异常(如访问违规、除零错误等)。每个线程有一个异常处理链表,由一系列异常处理记录(EXCEPTION_REGISTRATION_RECORD)组成,每个记录包含一个异常处理函数指针和一个指向下一个记录的指针。当异常发生时,系统会按链表顺序调用每个异常处理函数,直到找到能处理该异常的处理程序或链表结束。类比:异常处理链表像一串“异常处理锁链”,每个节点是“锁链环”,异常发生时系统按顺序检查每个环是否能“锁住”异常,若能则执行对应函数,否则继续检查下一个环。

3) 【对比与适用场景】

对比项Windows SEHC++ try-catch系统级异常处理(如内核)
定义Windows系统级异常处理机制,用于捕获用户态程序异常C++语言级异常处理,用于捕获程序逻辑异常内核中处理硬件异常或系统错误
特性链表结构,用户态和内核态均支持,异常处理函数可执行任意代码语言级,仅用户态,异常处理函数需符合语言规范处理硬件中断、系统调用错误等
使用场景捕获程序运行时异常(如缓冲区溢出、访问违规)处理程序逻辑错误(如数组越界、除零)处理系统级错误(如内存不足、硬件故障)
注意点异常处理函数指针可被覆盖,存在漏洞利用风险异常处理函数需正确处理,否则可能导致崩溃内核SEH更复杂,涉及系统稳定性

4) 【示例】
伪代码展示缓冲区溢出覆盖SEH指针:

void vulnerable_function() {
    char buffer[8];
    // 溢出点
    strcpy(buffer, "A" * 12); // 假设输入长度为12,缓冲区大小8,导致溢出
    // 溢出后,覆盖异常处理函数指针(位于栈上,紧邻缓冲区)
    // 假设异常处理函数指针地址为0x7ffdfc0,恶意代码地址为0x7ffdfc4
    *(DWORD*)0x7ffdfc0 = 0x7ffdfc4;
}

void malicious_code() {
    // 恶意代码,如执行系统命令
    system("calc.exe");
}

解释:函数调用时,输入数据溢出缓冲区,覆盖了异常处理函数指针,使其指向恶意代码地址,当发生异常(如访问违规)时,系统调用恶意代码。

5) 【面试口播版答案】(约90秒)
“面试官您好,关于Windows SEH的工作原理,核心是系统通过异常处理链表捕获程序异常。每个线程有一个链表,由EXCEPTION_REGISTRATION_RECORD结构组成,每个记录包含异常处理函数指针和下一个记录的指针。当异常发生时,系统按链表顺序调用处理函数,直到找到匹配的处理程序。漏洞利用方面,缓冲区溢出可覆盖异常处理函数指针,跳转执行恶意代码。比如,函数中缓冲区溢出后,将异常处理函数指针改写为恶意代码地址,异常发生时执行恶意代码。防御措施包括数据执行保护(DEP)防止代码执行,地址空间布局随机化(ASLR)随机化异常处理函数地址,以及堆栈保护(如/GS编译选项)防止溢出覆盖SEH指针。总结来说,SEH是异常处理机制,攻击者可利用溢出覆盖其指针实现代码执行,而DEP、ASLR等是常见防御手段。”

6) 【追问清单】

  • 问:SEH如何处理不同类型的异常(如访问违规、除零错误)?
    回答要点:系统根据异常类型(如EXCEPTION_ACCESS_VIOLATION)匹配异常处理函数,不同异常类型对应不同的处理逻辑,处理函数需检查异常码并决定是否处理。
  • 问:SEH与硬件异常(如页面错误)的关系?
    回答要点:硬件异常(如页面错误)会触发内核的异常处理,内核会调用对应的异常处理函数(如页面错误处理程序),而用户态的SEH处理程序在内核态异常处理之后执行。
  • 问:如何绕过SEH的防御(如DEP、ASLR)?
    回答要点:绕过DEP可通过返回导向编程(ROP)执行现有代码;绕过ASLR可通过信息泄露获取异常处理函数地址,或利用堆喷(heap spray)覆盖SEH指针。
  • 问:内核态的SEH与用户态的SEH有何区别?
    回答要点:内核态SEH更复杂,处理系统级错误(如内存分配失败),异常处理函数是内核驱动或系统服务,用户态程序无法直接访问,但内核漏洞仍可利用SEH实现提权。
  • 问:SEH处理函数的调用上下文(如寄存器状态)如何?
    回答要点:异常发生时,系统保存当前线程的寄存器状态(如EIP、ESP等),异常处理函数执行时使用这些上下文,处理完异常后恢复寄存器并继续执行。

7) 【常见坑/雷区】

  • 混淆SEH与C++ try-catch:错误认为SEH是语言级异常处理,实际是系统级,用于捕获硬件异常。
  • 错误描述异常处理链表的顺序:认为链表从后往前处理,实际是从头到尾。
  • 忽略内核态的SEH:只讲用户态,忽略内核中SEH的重要性,导致对内核漏洞利用理解不足。
  • 防御措施说错:比如认为ASLR随机化异常处理函数指针,实际ASLR随机化的是代码和数据地址,异常处理函数地址可能被覆盖但ASLR随机化后难以预测。
  • 漏洞利用细节错误:比如认为覆盖SEH指针后直接执行代码,忽略异常发生时的触发条件(如访问违规),实际需要异常触发(如访问被覆盖的内存)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1