花了两个小半晚上的时间将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. 简单几句话总结Unicode,UTF-8和UTF-16

    概念 先说一说基本的概念,这包括什么是Unicode,什么是UTF-8,什么是UTF-16. Unicode,UTF-8,UTF-16完整的说明请参考Wiki(Unicode,UTF-8,UTF-16 ...

  2. undefined reference to `Spreadsheet::staticMetaObject'

    <C++ GUI Qt 4 编程>学习 一.遇到的问题 在学完第4章后,Spreasheet程序也已经写好了.在用 FindDialog 搜索时发现没有效果. 二.解决过程 调试跟踪代码, ...

  3. It will affect staff as well.

    Premier Foods has reduced its number of suppliers dramatically in the last 12 months. In 2013 it mad ...

  4. 关于mongodb的复合索引新功能

    最新在做一个项目,由于查询字段较多,且查询较频繁,所以我做了一个复合索引,将所有需要查询的字段都做到索引里,做了一个名为s_1_m_1_c_1_v_1_year_1_month_1_week_1_da ...

  5. 字符串判断设置TextView高度

    问题:项目中需要根据字符串的长度判断Textview的高度   一.如果全是英文的也比较容易,根据长度判断从而设置mTextView的高度就好. double temp = str.length(); ...

  6. mysql 查看数据库、表的基本命令

    1:show databases; 查看所有的数据库,等同于select schema_name from information_schema.schemata\G.\G 替换;,以纵向报表的形式输 ...

  7. hdu 2062

    ps:11版的最后一题...是个递推题...比如n=5,推出首数字后,n--,继续找下一个 代码: #include "stdio.h" ]; ]; int main(){ lon ...

  8. UIKit框架之UIGestureRecognizer

    ---恢复内容开始--- 1.继承链:NSObject 2.UIGestureRecognizer的子类有以下: UITapGestureRecognizer :点击 UIPinchGestureRe ...

  9. 在CSS中通过@font-face属性来实现网页中嵌入特殊字体。

    首先获取要使用字体的三种文件格式.EOT..TTF或.OTF..SVG,确保能在主流浏览器中都能正常显示该字体..EOT,适用于Internet Explorer 4.0+.TTF或.OTF,适用于F ...

  10. Thinkphp_基础(2)URL模式

    URL请求 ThinkPHP采用单一入口模式访问应用,对应用的所有请求都定向到应用的入口文件,系统会从URL参数中解析当前请求的模块.控制器和操作,下面是一个标准的URL访问格式: http://se ...