Windows漏洞利用开发教程Part 5 :返回导向编程(ROP)

* 本文作者:zusheng,本文属FreeBuf原创奖励计划,未经许可禁止转载

一、前言

漏洞——信息安全界最常见的词汇,在百度百科是这样描述的:

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。

本文主要介绍的是Windows软件漏洞的利用开发教程。我花了大量的时间来研究了计算机安全领域Windows漏洞利用开发,希望能和大家分享一下,能帮助到对这方面感兴趣的朋友,如有不足,还请见谅。

前文回顾

Windows漏洞利用开发教程Part 1 Windows漏洞利用开发教程Part 2:Short Jump Windows漏洞利用开发教程Part 3:Egghunter Windows漏洞利用开发教程 Part 4:SEH

二、准备阶段

欢迎来到Windows漏洞利用开发的第五篇文章,今天我们将讨论一种返回导向编程(ROP)技术,该技术通常用于解决被称为数据执行保护(DEP)的安全措施。DEP是数据执行保护的英文缩写,全称为Data Execution Prevention。数据执行保护(DEP) 是一套软硬件技术,能够在内存上执行额外检查以防止在系统上运行恶意代码。

到目前为止,我们一直在使用Windows XP系统环境来学习如何攻击具有较少安全机制的操作系统。经过前面的几篇文章,我们是时候换一套新的系统环境啦,对于本教程,我们将使用Windows 7系统环境。

接下来我们再次在虚拟机中安装Immunity Debugger,Python和mona.py。详情请看第一篇文章。

准备就绪后我们开始学习ROP,目标软件是VUPlayer,查看漏洞详情或下载存在漏洞的软件请看下述链接:

在开始之前,我们还需要确保Windows 7虚拟机的DEP已打开。

打开控制面板,系统和安全->系统,然后点击高级系统设置

点击设置,设置数据执行保护为下图所示

三、漏洞利用开发分析

开始和之前是差不多的步骤,这也是漏洞利用开发必不可少的步骤,所以我们不再做详细介绍了,只是大致演示一下怎么分析获取到一些必需的数据。

确认漏洞

首先我们肯定需要编写一个脚本来生成payload测试漏洞,这个漏洞在之前文章有介绍过。

我们是怎么简单怎么来,主要生成一个3000字符的测试文件test.m3u

使用Immunity Debugger打开软件VUPlayer.exe,在打开的对话框中点击file-openplaylist打开测试文件test.m3u或者将测试文件test.m3u拖拽到VUPlayer对话框,可以发现EIP被A字符串覆盖。

EIP offset

接下来就是寻找EIP的偏移量,很简单,我们使用mona来寻找

生成测试字符:

继续上面步骤后,查看EIP被覆盖的值

使用mona找到偏移量1012

JMP ESP

接下来就寻找一个JMP ESP,为什么要寻找它,前面也介绍过了,通过将EIP覆盖为它的地址跳出这样就可以非常方便的布局堆栈,确保shellcode顺利执行。

寻找JMP ESP的mona指令大家还记得吧

这样我们就得到了EIP要覆盖的地址0x1010539f

测试代码

现在可以加入模拟shellcode来测试一下是否会顺利执行shellcode

使用Immunity Debugger打开软件VUPlayer.exe,在打开的对话框中点击file-openplaylist打开测试文件test.m3u或者将测试文件test.m3u拖拽到VUPlayer对话框

你可以发现我们的shellcode并没有执行,如果继续下去程序就会崩溃,这是因为数据执行保护(DEP)阻止了我们shellcode的执行从而导致了程序的崩溃。但是,我们发现JMP ESP是执行了,所以说我们可以执行一些代码,但这条代码必须是现有的,就像我们之前可以运行的JMP ESP一样,它存在被允许执行的代码段中。这也正是ROP技术的关键所在。

四、ROP分析及构建

现在我们来看一下问题的核心是什么,DEP阻止了操作系统将我们的0xCC解释为INT指令,而不是它不知道0xCC是什么东西。如果没有DEP,操作系统就会知道0xCC是个INT指令,然后继续执行这个指令。启用DEP后,某些内存段就会被标记为NON-EXECUTABLE (NX),意思就是操作系统不会再将数据解释为指令。但是DEP没有说我们不能执行标记为可执行的现有程序指令,比如组成VUPlayer程序的代码,这在前面我们可以执行JMP ESP代码就可以看出了,因为该指令是在程序本身中找到的,被标记为可执行,因此程序可以运行。然而我们加入的shellcode是新的,所以它被放在了一个标记为不可执行的内存段。

ROP思想

现在我们已经接触到ROP技术的核心了,就是一个面向返回编程技术。核心思想就是收集一些现有的程序汇编指令,这些指令没有被DEP标记为不可执行,然后将它们链接在一起,告诉操作系统让我们的shellcode区域可执行。

我们收集的这些汇编指令被称为小配件(gadgets),这些小工具通常是一堆地址的形式,这些地址指向有用的汇编指令,然后是返回或RET指令,以开始执行链中的下一个小配件。这就是为什么它被称为面向返回编程。

我们怎么才能将shellcode区域标记为可执行呢?在Windows操作有很多办法,本文我们将使用VirtualProtect()函数,想详细了解这个函数请看下述链接:

介绍完理论,现在我们就要来实战构建。

构建ROP Chain

首先,我们来看看想成功执行VirtualProtect()函数,需要哪些参数:

了解完参数,我们分析看看这些参数怎么设置,lpAddress参数肯定设置为我们shellcode,dwSize设置为0x201,flNewProtect设置为0x40(常数,具体看下述链接),最后设置lpflOldProtect为任何静态可写的位置。接下来调用我们刚刚设置的VirtualProtect()函数就行了。

首先,让我们找到小配件来构建VirtualProtect()函数所需的参数,点击e来获取属于VUPlayer的可执行模块。

要从我们选择的模块找到可用小配件列表,您可以在Mona中使用以下命令:

查看Mona生成的rop_suggestions.txt和rop.txt文件

让我们来构建ROP chain

首先,让我们出栈一个值到EBP中,后面调用PUSHAD:

通过取反得到值0x201,然后将值放入到EBX寄存器,作为参数dwSize的值

接下来,同样道理得到值0x40,然后将值放入到EDX寄存器,作为参数flNewProtect的值

然后我们需要找到一个可写位置地址,然后将值放入寄存器ECX中,作为参数lpflOldProtect的值

为了等下调用调用PUSHAD,我们将一些值放入到EDI和ESI寄存器中

最后,我们放入函数VirtualProtect()的地址来进行调用,EAX寄存器的值就是0x1060e25c

接下来就很简单了,将我们设置的VirtualProtect()的寄存器压入堆栈,直接用了PUSHAD和JMP ESP,PUSHAD压入堆栈,JMP ESP转到执行。

PUSHAD将按以下顺序将寄存器值放在堆栈上:EAX、ECX、EDX、EBX、ESP, EBP, ESI,EDI。

Python:

五、漏洞利用开发实现

再写脚本之前,我们要注意一下,现在我们要覆盖的EIP地址只需要跳转过去马上回来就行了,所以我们直接找个RETN指令地址就行啦。

经过上面的分析,实现起来就很简单了,具体请看下面代码和注释:

使用Immunity Debugger打开软件VUPlayer.exe,在打开的对话框中点击file-openplaylist打开测试文件test.m3u或者将测试文件test.m3u拖拽到VUPlayer对话框,shellcode成功执行。

堆栈情况:

六、总结

使用!mona rop命令,在日志文件夹rop_chains.txt文件中也会自动生成一个完整的ROP chain,当然重点在于理解,如果自动生成的ROP chain在使用过程中出错,就需要自己慢慢去分析并修改一些东西了。有攻必有防,攻与防总是相对的,在这里感谢无私分享技术的安全研究人员,没有他们的分享就没有这篇文章。当然,我自认为自己了解还是太少了。还是那句话,本人水平有限,如有不足,还请各位兄弟指出。 * 本文作者:zusheng,本文属FreeBuf原创奖励计划,未经许可禁止转载

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2018-06-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏智能大石头

NewLife.Net——构建可靠的网络服务

1543
来自专栏Golang语言社区

【Go 语言社区】Web 通信 之 长连接、长轮询(long polling)--转

基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性。 一、什么是长连接...

1.1K3
来自专栏北京马哥教育

《linux下crontab的深入分析》

一)cron服务的介绍 cron是Linux系统下一个自动执行指定任务的程序. cron服务要通过命令启动和停止,在Linux上可以通过/etc/init.d/...

2835
来自专栏张善友的专栏

SmartGit:Git版本控制系统的图形化客户端程序

Git最初是一个由林纳斯·托瓦兹为了更好地管理linux内核开发而创立的分布式版本控制/软件配置管理软件。后来Git内核已经成熟到可以独立地用作版本控制。很多有...

2075
来自专栏芋道源码1024

Java中高级面试题(4)

这里选了几道高频面试题以及一些解答。不一定全部正确,有一些是没有固定答案的,如果发现有错误的欢迎纠正,如果有更好的回答,热烈欢迎留言探讨。

1850
来自专栏北京马哥教育

在Python中使用Elasticsearch

在这篇文章中,我将讨论Elasticsearch以及如何将其整合到不同的Python应用程序中。

3530
来自专栏web编程技术分享

一分钟学会在JavaWeb项目中配置数据源

3229
来自专栏黑泽君的专栏

消除windows下的PyCharm中满屏的波浪线

1、PyCharm使用了较为 严格的PEP8 的检查规则,如果代码命名不规范,甚至多出的空格都会被 波浪线 标识出来,导致整个编辑器里 铺满了波浪线,右边的滚动...

4711
来自专栏Java成神之路

Web 通信 之 长连接、长轮询(long polling)

基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性。

4433
来自专栏Kiba518

C#——Nhibernate探索

该版本可能是最新版,我下载的4.0.4.GA。其中GA意思我没搞清楚。不过应该不重要。

1123

扫码关注云+社区

领取腾讯云代金券