0day安全safeSEH绕过实验
0x00 实验环境
- 操作系统:xp sp3
- 编译器:vs 2010
- 编译选项:Release版本;关闭优化,DEP,ASLR
0x01 从堆中绕过
实验代码和书中类似:
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
char shellcode[] = …;
void test(char *input)
{
char str[240];
strcpy(str, input);
int zero=0;
zero = 1/zero;
}
int _tmain(int argc, _TCHAR* argv[])
{
char *buf=(char *)malloc(500);
__asm int 3
strcpy(buf, shellcode);
test(shellcode);
return 0;
}
240个字节试水后,malloc在堆上分配的地址为0x00393F48,strcpy之后还需要100字节才能覆盖到SE handler,而safeSEH不会校验指向堆中的指针,所以构造shellcode布局如下:
轻松exploit:
0x02 利用未启用SafeSEH模块绕过
实验代码和书中类似:
#include "stdafx.h"
#include <string.h>
#include <Windows.h>
char shellcode [] = …;
DWORD MyException(void)
{
printf("This ia an exception");
getchar();
return 1;
}
void test(char * input)
{
char str[240];
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"));
//char str[240];
__asm int 3
test(shellcode);
return 0;
}
起初在main函数中开辟的数组感觉没有就先注释掉了。240字节试水,strcpy后栈帧环境如下:
向下溢出20个字节即可覆盖SE Handler,在这里使用的是和书中相同的没有开启safeSEH的dll文件中的pop pop ret地址0x11121068。在调试过程中发现dll编译链接不成功,原来是书中代码少包含了windows.h头文件。另一处是__asm int 3调用olldbg去调试时,发现总是无法加载插件,在Appearance中指定一下插件目录就可以了:
所以利用方式和前文绕过GS中探究的类似,将SE handler覆盖为pop pop ret地址,eip会转到0x0012FF5C去执行,其后再接上我们的payload就可以了,shellcode布局如下:
这样的布局在调试后会发现,就算payload的起始copy地址为0x0012FF60,一直到栈空间的末尾也才160个字节,无法完全复制236字节的payload,而且也会产生异常。所以在main函数中字符数组str[240]的定义实际上就是为了抬高栈顶,让后面有足够的空间strcopy我们的shellcode,最终exploit效果如下:
0x03 利用加载模块之外的地址绕过
实验代码和书中类似:
#include "stdafx.h"
#include <string.h>
#include <Windows.h>
char shellcode [] = …;
DWORD MyException(void)
{
printf("This ia an exception");
getchar();
return 1;
}
void test(char * input)
{
char str[240];
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;
}
这个实验的内容和前一个实验的内容也相似,也是覆盖SE handler的地址,因为这里找的是模块之外的跳板地址,所以safeSEH就起不到作用了。通过ollyfindaddr找到的是位于0x00280b0b的指令call [ebp+0x30],而这个[ebp+0x30]指向的刚好就是Pointer to next SHE record的地址:
Next指针处就和书中的一样填充为一个短跳的指令\xeb\xf6\x90\x90(短跳的字节码为\xeb,\xf6为-10的补码),短跳之后在接一个近跳(\xe9)的指令,因为近跳指令地址和shellcode在栈中的起始地址相差253个字节,所以近跳后接的16位位移为\xff\xff\xff\x03:
最终shellcode布局如下:
这种短跳结合近跳的方法也适用于上一个实验的shellcode构建(就不用开始的抬高栈顶了),所以exploit效果如下:
0x04 利用Adobe Flash Player ActiveX控件绕过
这里就是借助未开启SafeSEH的Flash Player ActiveX控件,在具有溢出漏洞中的AxtiveX控件中,覆盖SE handler地址,利用未启用SafeSEH来模块中的跳板地址来绕过。实验中也是因为程序会对栈中数据有些破坏,所以就用短跳指令去执行payload,思路大体都是类似的,详见他人的实践:http://www.freebuf.com/articles/web/149886.html,我就不赘述啦。