花了两个小半晚上的时间将0day安全这本书的绕过DEP的第一个实验做了,这里做些笔记。

  Ret2libc 我现在自己的理解就是在开启DEP保护的情况下,在程序的其他的可执行位置找到可以满足我利用要求的指令,形成一个可执行的指令序列,达到成功执行shellcode的目的。

  那么利用Ret2libc的第一个方法就是通过ZwSetInformationProcess函数,这个API可以直接将进程中的DEP保护关闭,执行shellcode。

  首先需要了解的是一个进程的DEP标识是在KPROCESS结构中的_KEXECUTE_OPTIONS中,_KEXECUTE_OPTIONS的具体结构是这样子的:

  

  标识位的前4bit和DEP相关,当DEP开启Pos0置1,DEP关闭Pos1置1,Pos3置1表示标识位都不能修改,所以影响DEP状态的是前2位,只需要设置成00000010就可以。

  接下来是ZwSetInformationProcess函数:

  

  ZwSetInformationProcess函数的第一个参数显而易见是进程的句柄,设置为-1的时候标识当前进程,第3个参数是用来设置_KEXECUTE_OPTIONS的,只需要这个参数二进制值最后两位是01即可,第四个参数是第三个参数的长度。

  接下来是具体的实验步骤:

  根据书上的指导,用了OllyFindAddr这个插件,Disable DEP -> Disable DEP<==XP SP3搜索,不太清楚为什么是从这里开始而不是直接跳到ZwSetInformationProcess函数的入口,这里留个疑问,用了这个插件OD搜索到的地址同样是0x7c93cd24, 指向的汇编指令是CMP AL,1,所以为了满足这个判断条件,第一步是找到将AL赋值为1的指令,所有 的MOV EAX,0x1  ; MOV AL,1 理论上都可以,这里我用了ID的mona插件,查找到相应的指令的地址就ok,为了稳妥,选用了和书上一样的地址,所以我的ROP链现在是这样 :

"\x52\xe2\x92\x7c" // MOV AL,1
"\x24\xcd\x93\x7c" // 关闭DEP的起始地址

  当然ROP链会根据出现的情况进行调整,接下来正如同书上写的情况同样,运行到对EBP-4这个地址写数据的时候出现异常了,原因是之前的字节覆盖了EBP-4这个地址内容,所以程序写入了一个无效的地址,需要修正EBP,然后运行到此查看各个寄存器的值,发现ESP的值适合赋给EBP,所以查找PUSH ESP; POP EBP; RETN的指令,修正ROP是这样:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d" //修正EBP
"\x24\xcd\x93\x7c"

  继续运行,在CALL ZwSetInformationProcess处下断点,观察ZwSetInformationProcess的参数情况,也就是注意ZwSetInformationProcess用来设置_KEXECUTE_OPTIONS的第三个参数,这里刚刚好是0x22(00100010),最末两位是01,不需要对其进行修改。继续往下走,走到0x7c93cd6f, RETN 4 这个地方,此时ESP的值指向的地址是0x00000004, 这是之前ZwSetInformationProcess函数的参数压栈的结果,所以在修正EBP以后,要对ESP进行修正,防止影响ROP。

  然后根据书上的方法找到RETN 0x28这个指令的地址,所以现在的ROP是这样:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d"
"\x19\x4a\x97\x7c" // 增大ESP
"\x24\xcd\x93\x7c"

  但是这样的问题是由于RETN 0x4的偏移的原因导致堆栈是这样的:

  

  ESP应该指向0x7c93cd24跳到关闭DEP的代码但是指向了堆栈的下一个,所以ROP修改为:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d"
"\x19\x4a\x97\x7c"
"\x90\x90\x90\x90"
"\x24\xcd\x93\x7c"

  这样就可以保证在增大ESP以后,程序进入关闭DEP代码的流程。

  接下来程序会顺利进入到关闭DEP代码,然后一直往下走,走到0x7c93cd6f这个地方,这时候发现ESP指向了之前用4个90填充的堆栈,这时候很显然,在执行0x0013febc这个指令地址以后,ESP会跳到0x0013fec4这个堆栈地址,显然,0x0013febc我们就可以放入jmp esp的指令地址,然后代码跳到0x0013fec4,这时候仔细观察堆栈我们可以发现有176个字节的shellcode离0x0013fec4这个地方有200个字节远,所以最后在0x0013fec4这个地方放上回跳200个字节的指令就可以了,因为此时DEP已经被关闭,所以堆栈可以放上可执行的代码。

  最后的ROP链:

"\x52\xe2\x92\x7c"
"\x85\x8b\x1d\x5d"
"\x19\x4a\x97\x7c"
"\xc7\x31\x5a\x7d"
"\x24\xcd\x93\x7c"
"\xe9\x33\xff\xff"
"\xff\x90\x90\x90"

几个小tips:

1. 汇编中LEAVE指令相当于 mov esp,ebp ; pop ebp

2. 最后的回跳指令在VC6中提取出回跳200字节的机器码

                                                                                              2015/9/21

                                                                                                          23:41

Ret2Libc 练习(1) -- ZwSetInformationProcess的更多相关文章

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

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

  2. OD: DEP & Ret2Libc

    Data Execution Prevention,数据执行保护,专门用来弥补计算机对数据和代码混淆这一天然缺陷. DEP 的原理是将数据所在的内存页(默认的堆.各种堆栈页.内存池页)标记为不可执行, ...

  3. OD: DEP - Ret2Libc via VirtualProtect() & VirtualAlloc()

    一,通过 VirutalProtect() 修改内存属性绕过 DEP DEP 的四种工作模式中,OptOut 和 AlwaysOn 下所有进程默认都开启 DEP 保护,这里如果一个程序自身需要从堆栈中 ...

  4. 缓冲区溢出基础实践(一)——shellcode 与 ret2libc

    最近结合软件安全课程上学习的理论知识和网络资料,对缓冲区溢出漏洞的简单原理和利用技巧进行了一定的了解.这里主要记录笔者通过简单的示例程序实现缓冲区溢出漏洞利用的步骤,按由简至繁的顺序,依次描述简单的 ...

  5. Linux下利用Ret2Libc绕过DEP

    Linux下利用Ret2Libc绕过DEP ⑴.  原理分析: 系统库函数通常是不受DEP(关于DEP,可以查看我之前文章的详细介绍)保护的,所以通过将返回地址指向系统函数可以绕过DEP保护,所以可以 ...

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

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

  7. PWN菜鸡入门之栈溢出 (2)—— ret2libc与动态链接库的关系

    准备知识引用自https://www.freebuf.com/articles/rookie/182894.html 0×01 利用思路 ret2libc 这种攻击方式主要是针对 动态链接(Dynam ...

  8. pwn之ret2libc

    0×01 利用思路 ret2libc 这种攻击方式主要是针对 动态链接(Dynamic linking) 编译的程序,因为正常情况下是无法在程序中找到像 system() .execve() 这种系统 ...

  9. pwn200,一道不完全考察ret2libc的小小pwn题

    pwn200 ---XDCTF-2015 每日一pwn,今天又做了一个pwn,那个pwn呢???攻防世界的进阶区里的一道小pwn题,虽然这个题考察的知识不多,rop链也比较好构建,但是还是让我又学到了 ...

随机推荐

  1. 存储过程详解与java调用(转)

    存储过程的一些基本语法: --------------创建存储过程----------------- CREATE PROC [ EDURE ] procedure_name [ ; number ] ...

  2. Spring事务配置的五种方式(转载)

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  3. 样式PC和手机页面

    /*媒体查询--当页面大于1200px时*/ @media (min-width: 1200px) { } /*在922和1199像素之间的屏幕里,中等屏幕*/ @media (min-width: ...

  4. pointer to function

    指针.函数.数字.结构体.指针函数.函数指针 初学不好区分,做点儿实验来有效区分一下,以下代码采用dev-C++平台测试 //pointer to fucntion 函数功能是 基地址加偏移量得到偏移 ...

  5. USACO 刷水

    BZOJ 1666 水.. BZOJ 1579 分层图最短路. BZOJ 1782 从一开始若某头牛停在U,那么U的子树的时间都会加一用BIT维护DFS序就行了 BZOJ 1572 贪心+堆 排序后查 ...

  6. tab使用 TabActivity TabHost Tabspec常用方法

    本文是参考Android官方提供的sample里面的ApiDemos的学习总结.   TabActivity   首先Android里面有个名为TabActivity来给我们方便使用.其中有以下可以关 ...

  7. wamp出现You don’t have permission to access/on this server提示的解决方法

    本地搭建wamp 输入http://127.0.0.1访问正常,当输入http://localhost/ apache出现You don't have permission to access/on ...

  8. EasyUI中Grid标题居中方法(jquery实现方法)

    $(".panel-title").css("text-align", "center"); 一句话搞定,就是这么随意

  9. easyui datebox 扩展清空按钮及日期判断

    <input id="EndHavDate" class="easyui-datebox" data-options="prompt:'请选择结 ...

  10. Xcode6中如何去掉默认的Main.storyboard

    xcode 6取消了 Empty Application 模板来创建一个工程,创建出来的有工程多了Main.storyboard,默认加载Main.storyboard,但是有很多人还想用代码来实现U ...