DOP_SR

2017-12-11  本文已影响0人  欧阳拽白

今天展示的是2016年IEEE S&P安全会议的一篇Data-Oriented Programming,我们简称DOP攻击。

在讲DOP之前,我们首先要看一下ROP。ROP全称Return-Oriented Programming ,顾名思义,就是以返回地址为目标的攻击手段。攻击者首先通过内存漏洞改写当前过程调用的返回地址,当过程调用结束了执行返回操作的时候,就陷入攻击者的目标代码处;随后攻击者通过串联事先在目标程序和共享库中找到的指令片段,来执行恶意语义。这些指令片段我们称之为gadget,每个gadget都是以ret指令结尾。

我们可以看到,ROP这类攻击的本质上是对程序控制流的劫持,操控程序的控制流。于是,有学者提出保护控制流完整性的策略CFI,之后针对CFI的研究层出不穷,理论上已经可以多种方法实现控制流的完整性检查。DOP的目标和ROP是一致的,但是它只操控程序的数据段,而不改变程序的控制流图,因此可以绕过CFI的检查。

DOP的前身追溯到2005年S&P安全会议的一篇“Non-Control Data Attacks Are Realistic Threats”,讲述了非控制数据攻击的方法;随后2015年S&P安全会议上又出现一篇“Automatic Generation of Data-Oriented Exploits”,讲述了自动化构造非控制流数据攻击的方法。图中给出了一个数据攻击的例子,攻击者通过内存漏洞直接改写pw->pw_uid的值为0,这样就使应用程序获得了root权限。可以看到这种攻击根本不会改变控制流。但是这类数据攻击一眼看上去,令人直觉上觉得攻击语义十分有限,只能改变存在数据段的条件变量或者泄露内存敏感内容。

但是DOP在现实中找到了这段代码:图中第7行readData存在内存漏洞,它可以溢出缓冲区数组buf,覆盖到buf之前的所有变量,那下面这整个循环就在攻击者的控制之下。攻击者可以控制循环条件,选择分支的条件,来实现各种赋值操作,解引用操作,逻辑运算操作。在这个例子中,12行13行的的操作我们称之为DOP的gadget,而攻击所需的循环我们称之为dispatcher,中文可以理解为调度器。

论文为了系统化DOP攻击,定义了MINDOP语言,包含六种操作,分别是:逻辑运算,赋值操作,加载和存储操作,跳转操作和条件跳转操作。这些操作在真实机器上都很容易找到相对应的gadget。前四种很容易理解,只要找到对应的指针操作即可。那为什么是必须是指针操作呢,因为在DOP中我们是对内存数据进行操作,通过覆盖指针值,我们很容易指向需要操作的内存数据段。

我们再来看下所谓的dispatcher,之前展示的例子中这个while循环就是一个dispatcher。dispatcher有个所谓的selector,控制需要用到的gadget,在该例子中就是type指针。

有了dispatcher后,我们来看一下如何实现MINDOP操作中的跳转语义。在这个例子中,第五行的函数是一个dispatcher,该dispatcher接收一个输入cmd来完成数据gadget,而cmd在第四行通过指针数组buf来赋值,指针数组buf里存储的是n轮操作的攻击语义,每轮操作后,更新cmd的值为下一个buf的指针值。那如何实现跳转语义呢,我们只要在当前轮操作完成后,更改cmd的值到buf数组的某处,比如buf[i-1],这样dispatcher就回到第i轮进行数据操作了。

上一篇下一篇

猜你喜欢

热点阅读