漏洞挖掘的艺术-面向二进制的静态漏洞挖掘 - FreeBuf网络安全行业门户
本文首发于“合天智汇”公众号 作者: 萌新
0
本文是本系列的第二篇,将对面向二进制程序的静态漏洞挖掘技术进行介绍与分析。
面向二进制程序的静态漏洞的挖掘技术由于缺少源代码中的结构化信息,面临着值集分析(vaule-set analysis,VSA)与控制流恢复不精确的问题,但是二进制程序相对于源码而言更容易获得,所以这方面的研究工作一直都有新的研究动态,并且会在第2部分介绍目前流程的两种技术。在进一步分析之前,我们首先来具体解释前文提出的两个问题。
1
1.1
值集分析是一种结合数值分析和指针分析的静态分析算法。VSA是一种基于抽象解释的、流敏感、上下文敏感、支持过程间分析的方法。VSA首先建立抽象内存模型,恢复可执行程序中的变量并用抽象地址表示,然后对每条指令静态计算抽象地址可能包含的值的jihe。
典型的值集分析算法的伪码表示如下
上图的jiheW被称为word-list,其操作包括add,removeNext,分别用于添加和移除项。Word-list按照拓扑顺序进行排序,初始化时包含着基本块的入口点,用于指示从此处开始正向分析。while循环的每次迭代里,Analysis函数都会在第6行被调用来分析选中的基本块。Analysis会基于输入状态产生大量的输出状态,那些变化的输出状态会被添加到word-list中。当在同一基本块上有两个输入状态时,VSA将在第11行将两个输入状态合并为新的输入状态。合并操作将合并抽象状态中每个变量的值集。变量的合并运算方程式如下所示
当程序读写内存时,根据目的地址的值集和将要读写的内存地址的长度,我们可以检测出它是否超过了对应变量的空间大小。如果超过,则可以作为一个潜在的漏洞上报。然而,由于VSA获得的值集是近似的,并不精确,所以可能会导致较高的误报率。
这里有篇19年的硕士论文《二进制程序Use-After-Free漏洞挖掘技术研究》,里面介绍了基于值集分析来挖掘UAF,感兴趣的可以看看。
另外,这篇论文《DEEPVSA: Facilitating Value-set Analysis with Deep Learning for Postmortem Program Analysis》发表于USENIX Security 2019(信息安全领域四大顶会之一),介绍通过深度学习来辅助值集分析的研究。
1.2
控制流恢复不精确指的是静态分析不需要执行程序,只通过对二进制文件的结构和指令操作码进行分析,静态分析重视全局程序分析,因而有很高的代码覆盖率,但由于无法解决间接跳转的问题,导致无法获取完整的控制流信息。
我们来看看控制流图的静态恢复。
1.2.1
对二进制代码进行控制流分析,首先要完成对二进制代码的静态反汇编。根据区分代码和数据方式的不同,可以将静态反汇编策略分为:线性扫描反汇编、递归反汇编和启发式反汇编三种。目前应用最广的静态反汇编策略是基于程序静态控制流程的递归策略,IDA使用的就是递归下降的算法。由于这不是本文重点,就不展开了。
1.2.2
接下来就是基本块的划分
基本块是程序中一组顺序执行的语句序列,其中只有一个入口语句和一个出口语句。基本块是具有原子性的一组连续语句序列,控制从第一条语句流入,从最后一条语句流出,中途没有停止或分支,意味着当程序跳转至某基本块时,该基本块中的所有指令都将被执行到9。因此,覆盖执行了该基本块就等同于覆盖了基本块所有指令。以基本块为单位对反汇编效果
进行分析,相比于指令级粒度的分析更加高效。
基本块入口定义:
a)代码片段标签(_start 和_main 等是出现在代码段前的标
志)的下一条指令;
b)CALL 指令在指令顺序流的下一条指令;
c)跳转语句在指令顺序流的下一条指令。
基本块出口定义:
a)代码片段的最后一条指令;
b)CALL 指令;
c)跳转指令;
d)返回指令。
一般采用线性扫描指令的方法实现基本块的划分,如下所示
完成基本块划分之后,需要构建基本块之间的控制流关系
1.2.3
最后一步就是CFG控制流分析
如果在一个有序代码中,基本块 B2 跟在 B1 后,那么产生一个由 B2 指向 B1 的有向边。在对目标二进制程序完成基本块划分后,需要对基本块间的控制流转向进行分析,完成控制流的绘制,伪码如下
input:基本块列表 block
output:CFG
for i=1 to n do
x=block[i]_lastinstr
if x is a CTI then
建立一条由 block[i]到 x 跳转的 target 所在的 block[j]的有向边
else if x not a CTI then
建立由 block[i]到 block[i+1]的边
end for
return CFG
2
当前,二进制静态漏洞挖掘技术主要包括基于模式匹配和基于补丁比对的技术。
2.1什么是模式匹配?
在计算机科学中,模式匹配是检查给定的标记序列是否存在某些模式的组成部分的行为。与模式识别相反,匹配通常必须精确:“匹配或不匹配。”图案通常具有序列或树形结构的形式。模式匹配的用途包括输出令牌序列中模式的位置,输出匹配模式的某些组成部分以及将匹配模式替换为其他某些令牌序列。
针对二进制程序分析时,一般不会单独应用模式匹配技术,比如会和VSA相结合。以GUEB为例,其提出了二进制程序中UAF漏洞模式,并基于此模式挖掘出了ProFTPD程序中的漏洞。具体而言,首先抽象出二进制函数中的内存模型,然后采用VSA分析技术追踪堆分配和释放指令相关的操作变量,并基于此建立UAF模式。
全文是以一个例子进行驱动的,源码如下
这里注意,这里虽然给出了代码,但是文中的工作都是从二进制层面展开的,给出源码是为了方便说明。
首先抽象出内存模型
我们假设堆栈中的地址表示为相对于基址寄存器EBP的偏移量。由于过程间分析是通过过程内联实现的,因此每个堆栈元素都由(EBP0,偏移量)表示,其中EBP0是EBP的初始值。例如,p_index由(EBP0,?24)表示,p_global_save由(EBP0,?36)表示。全局变量具有由标识符表示的常量地址,此处为变量名(例如pglobal)。对于堆,我们将HE定义为所有可能的堆元素的jihe。HE的元素是(基址,大小),其中base是分配识别符,size是分配大小。这样的一对也称为一个chunk.PC是所有程序指针的jihe。我们定义了HA和HF,这两个函数分别关联每个点上所有当前分配或者未分配的jihepc(HA∈PC→P(HE),HF∈PC→P(HE),P(S)是S的密集) 。我们使用在静态指针验证中的经典的假设,认为每个分配都提供了一个新的内存块(尽管这种方法对于研究可利用性是不现实的,但足以检测漏洞)。
接着进行VSA,结果如下
GUEB的最后一步,即从二进制层面提取出UAF漏洞模式的子图,如下所示
此子图对于研究UAF是否可利用以及如何利用非常有用:例如,在我们的示例中,在第33行释放和取消引用时是否发生了新的malloc。
2.2
补丁指的是软件开发商为了修补软件系统的各种漏洞或缺陷所提供的修补程序。对于开源软件,补丁本身就是程序源代码,打补丁的过程就是用补丁中的源代码替换原有的代码。而对于闭源软件,厂商只提供修改后的二进制代码,例如微软的Windows系统补丁。这时就需要使用二进制代码比对技术,定位补丁所修补的软件漏洞。
基于补丁对比的漏洞挖掘, 是指通过比较分析原始程序与漏洞修复后的更新程序的差异, 依据已知漏洞对应的软件缺陷位置寻找新漏洞的一种漏洞挖掘方法.补丁发布与部署之间存在较长的时间窗口, 因此, 通过补丁漏洞挖掘迅速提取漏洞特征, 对于软件运行安全检测和防护具有重要意义.目前, 软件自身的复杂性导致简单地进行指令对比难以快速逆向恢复漏洞细节并理解漏洞机理.与漏洞不相关的补丁修改造成相当程度的干扰, 补丁漏洞挖掘仍然需要软件基础理论的支撑.为此, 研究人员提出了多种基于图比较算法发现程序差异的基础分析工具, 如IDACompare、EBDS、BinDiff等.补丁漏洞挖掘的代表性工作是Brumley团队提出的APEG(automatic patch-based exploit generation)方案(2008 年的 IEEE S&P 会议上的论文)。
APEG核心思路是基于以下的假设条件,即补丁程序中增加了对触发原程序崩溃的过滤条件。因此,只要能够找到补丁程序中添加过滤条件的位置,同时构造 不满足过滤条件的“违规”输入,即可认为是原始程序的一个可利用的输入候选项。
该工作主要分为三个步骤:首先,利用二进制差异比较工具(例如 BinDiff 与 EBDS 等)找到补丁存在的位置,即补丁程序的检测点;
其次,找出不满足补丁程序检测点的输入数据作为原始程序的利用候选项;
最后,利用污点传播等监控方法筛选所有能够对原始程序造成溢出或者控制流劫持等崩溃发生的有效利用。
根据对微软所发布的多个补丁程序的实验结果表明,该方法具有较强的可靠性和实用性。
APEG 是对漏洞利用自动化构建的首次尝试,虽然核心思想较为简单,但由于其具有很强的可操作性,因此也得到了其他研究人员的普遍认可。
3
参考
1.http://blog.amossys.fr/intro-to-use-after-free-detection.html
2.https://www.bookstack.cn/read/CTF-All-In-One/160851
3.https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=8805076
4.http://www.jsjkx.com/CN/article/openArticlePDF.jsp?id=7401
5.http://jifeng-xuan.com/page/paper/jos_19.pdf
6.《软件漏洞自动利用研究进展》
7.https://www.slideserve.com/oriel/automatic-patch-based-exploit-generation-is-possible-techniques-and-iplications-powerpoint-ppt-presentation
8.http://www.jos.org.cn/htl/2018/1/5320.ht
9.《从自动化到智能化:软件漏洞挖掘技术进展》
4
实验推荐
基于栈溢出的攻击分析
https://sourl.cn/ic2eAd
栈溢出是由于C语言系列没有内置检查机制来确保复制到缓冲区的数据不得大于缓冲区的大小,因此当这个数据足够大的时候,将会溢出缓冲区的范围。
5
相关阅读
漏洞挖掘的艺术-面向源码的静态漏洞挖掘