使用ROP攻击绕过Windows的DEP

基础知识

DEP

  • DEP(Data Execution Prevention)意为数据执行保护,是Windows的一项安全机制,主要能够在内存上执行额外检查以帮助防止在系统上运行恶意代码,简单的说也就是以前直接将shellcode插入到堆栈中执行的方法已经不可行了,因为在开启DEP后,堆栈上的shellcode默认不可执行,因此也就不能使用以前的技术来成功攻击了。
  • DEP工作状态可分为四种:
    • Optin:默认仅将DEP保护应用于Windows系统服务和组件,对其他程序不予保护;
    • Optout:为排除列表程序外的所有程序和服务启用DEP;
    • AlwaysOn:对所有进程启用DEP的保护,不存在排除列表,此模式下DEP不可被关闭,该模式只能工作在64位的操作系统上;
    • AlwaysOff:对所有进程都禁用DEP,此模式下DEP不能被动态开启。

绕过DEP实现攻击

  • 绕过DEP的方法能大致分为两种:

    • 新建可执行内存区域,将shellcode复制进去;相关函数: VirtualAlloc() 、 HeapCreate() 、 WriteProcessMemory()
    • 通过系统API关掉DEP保护;相关函数: SetProcessDEPPolicy() 、 NtSetInformationProccess() 、 VirtualProtect()
  • 各函数在Windows各个系统的存在情况如下,其中(1)代表不存在,(2)代表将由于默认DEP策略设置而失败:

  • 绕过DEP需要构造ROP链,ROP链的作用就是用一连串的gadgets来实现这些函数的调用关闭DEP保护,然后转到shellcode上执行。

实验环境

  • 主机:kali

  • 靶机:Windows XP Professional SP3

  • 软件:Immnunity Debugger、OllyDbg、shellcode.exe(漏洞程序)

实践过程

DEP保护关闭

  • shellcode.exe是在网上找的一个漏洞程序,它的功能就是在启动时会在本地1000端口绑定socket并进行监听,当有用户连接并且用户发送大于64bytes的数据时,堆栈会发生溢出,从而产生攻击。

  • 在Windows XP SP3中,默认以Optin方式开启DEP,即仅将DEP保护应用于Windows系统服务和组件,对其他程序不予保护。shellcode.exe是用户进程,自然也不会受到DEP保护:

  • 首先,我们在没有DEP保护的情况下看程序能否成功溢出,在主机上进行nc监听,打开4444端口:

  • 然后在靶机中运行shellcode.exe程序:

  • 编写Python攻击代码exploit.py,将返回地址覆盖为0x7FFA4512(jmp esp指令),发送shellcode到靶机,然后回连主机的4444端口,编写完成后运行:

  • 可以看到,通过缓冲区溢出攻击,此时主机上成功获得了xp的shell:

DEP保护打开

  • 如图所示,在控制面板中设置打开DEP:

  • 重启靶机,再次运行shellcode.exe,发现出错了:

  • 使用OllyDbg进行调试,可以看到程序是成功溢出了并执行了jmp esp指令(0x7FFA4512):

  • 从上图中可以知道,在DEP开启的情况下是溢出成功了,但是shellcode处在堆栈中,由于DEP的保护,因此并不能触发执行,因而报错。

  • 因为SetProcessDEPPolicy函数简单且ROP链构建相对容易,所以我就构建ROP链来调用SetProcessDEPPolicy函数关闭DEP保护,然后转向shellcode执行。基础知识中提到ROP链是由gadgets构造的,要想快速的找到gadgets来构造链,可以用到Immunity Debugger上的一个python模块:mona.py,具体介绍可以参考这篇文档,将它下载后复制到Immunity Debugger的PyCommands目录下就可以使用了。

  • 使用Immunity Debugger载入shellcode.exe,然后可以查看当前程序加载的可执行模块:

  • 在下方命令行处输入命令!mona rop -m kernel32.dllkernel32.dll中进行扫描,查找完成后,会在IM Debugger的安装目录下生成报表文件,我们打开rop_chains.txt进行查看,找到SetProcessDEPPolicy的ROP链说明处,可以看到针对不同语言有不同的说明,有Ruby语言的、Python的、JavaScript等等,我们找到Python对应的说明:



  • 整个ROP链的最终构造结果是构造出一个特定的寄存器结果,就像上图所示的一样,因为我们知道PUSHAD是依次将EAX、ECX、EDX…ESI、EDI入栈,那么当我们通过ROP链构造好各个寄存器并通过gadget执行PUSHAD RETN后,此时堆栈的结构大概就是这个样子的:

  • 这里可以看到,入栈前我们将EDI和ESI的值存储为RETN指令的地址,然后会执行EBP处的SetProcessDEPPolicy函数,因为PUSHAD RETN在shellcode的上一个位置,执行完后ESP会指向shellcode,当SetProcessDEPPolicy执行完毕后会直接转到我们shellcode处执行(此时已经通过调用SetProcessDEPPolicy取消DEP保护了),所以经过分析可以看到我们构造的具体的ROP链:

0x????????,  # POP EBP # RETN
0x????????, # ptr SetProcessDEPPolicy(“SetProcessDEPPolicy”的指针)
0x????????, # POP EBX # RETN
0x00000000, # dwFlags
0x????????, # POP EDI # RETN
0x????????, # ptr RETN(“retn指令”的地址)
0x????????, # POP ESI # RETN
0x????????, # ptr RETN(“retn指令”的地址)
0x????????, # PUSHAD # RETN
  • 上面的问号代表我们需要寻找的ROP gadget的地址,这里还要指出一个问题,很多时候我们需要的gadget不一定能在当前程序的执行模块中直接找到,但是我们可以通过其他方法来实现,比如我想使得EBX为0x00000000,我们可以先找到POP EBX; RETN;,将EBX先赋值为0xffffffff,然后在找到INC EBX; RETN;,这样两个gadget合在一起执行达到了我们的目的。

  • 其实,刚才通过执行mona.py已经在IM Debugger安装目录下记录了一些小配件的地址,打开rops.txt,通过查找我们可以找到在0x7c87f30f处找到我们想要的ROP小配件:

  • 这里,我们可以重新在IM Debugger中利用mona.py模块来进行特定指令的查找,retn指令的机器码为\xc3,我们在命令行中输入!mona find -s '\xc3 -m kernel32.dll',命令执行完成后,结果会在IM Debugger安装目录下find.txt文件中,如下图所示:

  • 可以选择其中几个作为我们RETN的gadget,其他gadget的寻找方法和这个类似,通过mona.py最后找到的各个ROP gadget构成的ROP链如下所示:

0x77bf4f42,   # RETN
0x90909090,
0x7c80df32, # POP EBP # RETN
0x7c862144, # ptr to SetProccessDEPPolicy()
0x7c81ae28, # POP EBX # RETN [kernel32.dll]
0x00000000, # 0x00000000(dwFlags)
0x7c86ce63, # POP EDI # RETN [kernel32.dll]
0x77bf54c4, # ptr RETN
0x7c87b976, # POP ESI # RETN [msvcrt.dll]
0x77bf5502, # ptr RETN
0x77d23ad9, # PUSHAD # RETN [user32.dll]
  • 因为shellcode.exe在溢出点函数返回时是RETN 0x04,因此我加入了前两个ROP gadget进行过渡,使得整个ROP链能够串起来。

  • 最后将构造的ROP链与最开始编写的Python攻击代码重新结合一下,构成新的攻击代码exlpoit_dep.py

  • 然后,我们在系统开启DEP保护的情况下,使用新的攻击代码进行测试:

  • 可以看到成功得到了shell,至此使用ROP攻击绕过Windows的DEP成功:

使用ROP攻击绕过Windows的DEP的更多相关文章

  1. 【转】针对Android上的ROP攻击剖析

    引言       ROP(Return-oriented programming),即“返回导向编程技术”.其核心思想是在整个进程空间内现存的函数中寻找适合指令片断(gadget),并通过精心设计返回 ...

  2. 20145236《网络对抗》进阶实验——64位Ubuntu 17.10.1 ROP攻击

    20145236<网络对抗>进阶实验--64位Ubuntu 17.10.1 ROP攻击 基础知识 ROP攻击 ROP全称为Retrun-oriented Programmming(面向返回 ...

  3. 64位Ubuntu系统下ROP攻击

    64位Ubuntu系统下ROP攻击 基础知识 ROP攻击 ROP全称为Retrun-oriented Programmming(面向返回的编程)是一种新型的基于代码复用技术的攻击,攻击者从已有的库或可 ...

  4. 利用 ROP 技术绕过 DEP 保护的一次简单尝试

    \x 01 前言 DEP是数据执行保护的英文缩写,全称为Data Execution Prevention.数据执行保护(DEP) 是一套软硬件技术,能够在内存上执行额外检查以帮助防止在系统上运行恶意 ...

  5. Rop攻击

    参考:http://en.wikipedia.org/wiki/Return-oriented_programming Rop全称Return-Oriented Programming,就是对栈上的返 ...

  6. 预攻击 局域网 Windows 查看其它在线设备

    环境:win10 首先我发现,一个常用的命令用不了,如图: net view 按理来说,按Enter键之后显示应该出局域网内所有正在运行的电脑:(截图来自百度) 那么我试一下另外一个办法: 首先ipc ...

  7. 关闭windows的DEP

    1.与开启dep时一样,按组合键win+r打开运行窗口,输入cmd并按回车,如图所示:    2.调出命令提示符窗口后,输入bcdedit.exe/set {current} nx AlwaysOff ...

  8. Web常用编码以及攻击绕过笔记

    一.URL编码形式:"%"加上ASCII码(先将字符转换为两位ASCII码,再转为16进制),其中加号"+"在URL编码中和"%20"表示一 ...

  9. 如何检测Windows中的横向渗透攻击

    一.前言 横向渗透攻击技术是复杂网络攻击中广泛使用的一种技术,特别是在高级持续威胁(Advanced Persistent Threats,APT)中更加热衷于使用这种攻击方法.攻击者可以利用这些技术 ...

随机推荐

  1. Android 學習之旅!(1)

    就這樣就過去了一年加一個學期,現在是大二第二個學期而且是下半學期了,以前都是無所事事,沒事睡睡覺,打打遊戲就過去了,但是想到家境和以後的路,我還是決心自己找點東西學習下,以後出去還能有一技之長(雖然可 ...

  2. 速读《构建之法》(Build to win)有感

    通过这两天时间,我粗读了<构建之法>这本书.老实说,对于这样四百多页的一本书,刚开始把这样的任务当作是一种负担,然而当我开始真正接触它时却被它幽默有趣的风格所深深吸引,它不同于以往学习的教 ...

  3. 第五届蓝桥杯C++B组 地宫取宝

    代码: #include <bits/stdc++.h> using namespace std; #define ll long long const ll mod = 1e9 + 7; ...

  4. Glace:generator-jhipster, adding User entity enhancement management

    https://github.com/jhipster/generator-jhipster/issues/2538 jhipster,很好用的开发工具.国外知名度高,国内未普及,国外大公司在用. j ...

  5. Eclipse集成Tomcat报错:java.lang.OutOfMemoryError: PermGen space

    Eclipse集成Tomcat报错,使用Spring 4.3 框架,运行一段应用后,控制台报错: Unexpected death of background thread ContainerBack ...

  6. BFC——块级格式化上下文

    BFC(块级格式化上下文) 一.BFC是什么? 从样式上看,具有BFC的容器和普通的容器没有区别.从功能上看,具有BFC的容器可以看作是隔离了的容器,容器里面的元素不会影响到外面的元素,并且BFC具有 ...

  7. hibernate 中文文档

    转载:http://blog.csdn.net/kevon_sun/article/details/42850387 Hibernate Annotations 参考文档 3.2.0 CR1 目录 前 ...

  8. CentOS 显示历史执行过的命令以及用户历史命令缓存文件

    1.history命令用于显示历史执行过的命令 执行 history命令能显示出当前用户在本地计算机中执行过的最近 1000 条命令记录. 如果觉得 1000 不够用,还可以自定义/etc/profi ...

  9. 洛谷P2054 [AHOI2005]洗牌(扩展欧几里德)

    洛谷题目传送门 来个正常的有证明的题解 我们不好来表示某时刻某一个位置是哪一张牌,但我们可以表示某时刻某一张牌在哪个位置. 设数列\(\{a_{i_j}\}\)表示\(i\)号牌经过\(j\)次洗牌后 ...

  10. LOJ #6202. 叶氏筛法(min_25 筛)

    题意 求 \([L, R]\) 之间的素数之和 . \(L≤10^{10},2×10^{10} \le R \le 10^{11}\) 题解 一个有点裸的 min_25筛 ? 现在我只会筛素数的前缀和 ...