Ret2Libc 练习(1) -- ZwSetInformationProcess
花了两个小半晚上的时间将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的更多相关文章
- 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之ZwSetInformationProcess函数
1. DEP内存保护机制 1.1 DEP工作原理 分析缓冲区溢出攻击,其根源在于现代计算机对数据和代码没有明确区分这一先天缺陷,就目前来看重新去设计计算机体系结构基本上是不可能的,我们只能靠 ...
- OD: DEP & Ret2Libc
Data Execution Prevention,数据执行保护,专门用来弥补计算机对数据和代码混淆这一天然缺陷. DEP 的原理是将数据所在的内存页(默认的堆.各种堆栈页.内存池页)标记为不可执行, ...
- OD: DEP - Ret2Libc via VirtualProtect() & VirtualAlloc()
一,通过 VirutalProtect() 修改内存属性绕过 DEP DEP 的四种工作模式中,OptOut 和 AlwaysOn 下所有进程默认都开启 DEP 保护,这里如果一个程序自身需要从堆栈中 ...
- 缓冲区溢出基础实践(一)——shellcode 与 ret2libc
最近结合软件安全课程上学习的理论知识和网络资料,对缓冲区溢出漏洞的简单原理和利用技巧进行了一定的了解.这里主要记录笔者通过简单的示例程序实现缓冲区溢出漏洞利用的步骤,按由简至繁的顺序,依次描述简单的 ...
- Linux下利用Ret2Libc绕过DEP
Linux下利用Ret2Libc绕过DEP ⑴. 原理分析: 系统库函数通常是不受DEP(关于DEP,可以查看我之前文章的详细介绍)保护的,所以通过将返回地址指向系统函数可以绕过DEP保护,所以可以 ...
- 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之VirtualProtect函数
利用Ret2Libc绕过DEP之VirtualProtect函数 ⑴. 原理分析: i.相关概念: VirtualProtect()函数: BOOL WINAPI VirtualProtect( _ ...
- PWN菜鸡入门之栈溢出 (2)—— ret2libc与动态链接库的关系
准备知识引用自https://www.freebuf.com/articles/rookie/182894.html 0×01 利用思路 ret2libc 这种攻击方式主要是针对 动态链接(Dynam ...
- pwn之ret2libc
0×01 利用思路 ret2libc 这种攻击方式主要是针对 动态链接(Dynamic linking) 编译的程序,因为正常情况下是无法在程序中找到像 system() .execve() 这种系统 ...
- pwn200,一道不完全考察ret2libc的小小pwn题
pwn200 ---XDCTF-2015 每日一pwn,今天又做了一个pwn,那个pwn呢???攻防世界的进阶区里的一道小pwn题,虽然这个题考察的知识不多,rop链也比较好构建,但是还是让我又学到了 ...
随机推荐
- js倒计时显示
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>j ...
- c++ 之 编译期多态&运行期多态
编译时多态:程序运行前发生的事件 —— 函数重载.运算符重载 .模板 ——静态绑定 运行时多态:程序运行时发生的事件 —— 虚函数机制——动态绑定 template<typename T> ...
- [DNS][转]EDNS
随着业务的复杂化和多样化,RFC1035中定义的DNS消息格式和它支持的消息内容已经不足以满足一些DNS服务器的需求,于是,RFC2671 中提出了一种扩展DNS机制EDNS(Extension Me ...
- 【转】一名大学生的PHP进阶之路
我是一名河南某职业学院的学生,比较喜欢PHP开发 的 工作,自己也曾经自学过php,but如果没有老师教还真是难以坚持啊,在这里给大家说一下寒假在麦子的学习感受,首先说麦子每一堂课程都给了特别详细的 ...
- django进行model字段的自定义
相信大家一定有web应用被攻击的经历,数据库安全是一个网站的必须课.django有很好的orm,但sql注入,或其他方式的攻击都是无法完全屏蔽的. 所以一般数据库都会对用户数据,如text类型的数据进 ...
- C#窗体无法接受Keydown事件
问题一描述:当新建一个窗体时,添加KeyDown事件后,会正常处理,但是当添加有控件时,比如Button,TextBox,不会触发窗体的KeyDown事件,也没有调用KeyDown事件的处理程序. 原 ...
- PKu 2195
//PKu 2195 回家 By Loli_con Enail : Loli_con@outlook.com /* 题目叙述 ========= 在一个网格图中,有n个人和n个房子.每一个单位时间,每 ...
- [Java coding] leetcode notes
1, 如何不排序而找到最大,次大或者最小值? var int max1, max2, min1; iterate array once: update max1, max2, min1, for ex ...
- DotNetBar 第2课,窗口设置 Ribbon Form 样式
1. 新增 windows 窗体时,选 Ribbon Form 2. 窗体继承 Office2007RibbonForm 3. 设计窗口下面,删除 删除styleManager1 组件 窗口效果如下 ...
- Chapter 3.GDI/DirectDraw Internal Data Structures
说明,在这里决定跳过第二章,实在是因为里面涉及的内容太理论,对我而言又太艰深 3.1 HANDLES AND OBJECT-ORIRNTED PROGRAMMING In normal object- ...