Statically Discovering High-Order Taint Style Vulnerabilities in OS Kernels
- 1.Introduction
- 2.Overview
- 3.Static Analysis Design
- 4.Vulnerability Discovery And Warning Group
- 4.1.Vulnerability Detectors
- 5.Implementation
- 6.Evaluation
- 7.Limitation And Discussion
- 参考文献
作者来自University of California Riverside - Security Lab,同一团队其它系统安全方面的工作还包括:静态分析工具UBITech、Fuzz工具SyzDescribe。
1.Introduction
这篇paper可以说是对Dr.Checker在检测高阶漏洞时的改进。所谓高阶漏洞(high-order taint style vulnerabilities),值得是用户控制的输入(即taint source)在经过多次entry function调用后,通过复杂的控制/数据流传播到敏感操作(即taint sink)导致的漏洞。例如,一个entry function A() 将用户提供的参数复制到一个全局变量 G,而后该全局变量 G 在另一个enrty function B() 中被用作数组索引,而没有经过检查,导致了越界访问。
高阶的阶(order)指的是触发漏洞所需的入口函数调用的数量。与污点传播仅限于单个entry function调用(即一阶漏洞)相比,在有状态的软件(例如Linux内核)中经常出现的高阶漏洞更加难以发现。高阶漏洞检测面临2个challenge:
-
1.性能:检测工具需要高效地枚举cross-entry的污点传播路径。直观地说,由于多个entry function可以以任意顺序被调用,分析算法需要遍历许多可能的排列,并在不同排列中重复分析同一个entry function,这可能会增大分析开销。
-
2.精度:cross entry场景下的taint flow通常由多个entry function的taint flow拼接,因此不精确的taint flow可能会累积从而造成更多误报。
因此作者提出了SUTURE,其解决上述challenge的思路包括:
-
1.性能问题:首先独立分析每个entry function(仅分析一次),并为其局部和全局变量的taint behavior创建一个抽象摘要,然后在漏洞发现阶段,通过查询这些摘要按需构建高阶污点传播路径。这使得高效的高阶污点传播路径枚举成为可能。
-
2.精度问题:整合了许多创新和/或实用的功能来提高其精度。这些功能包括通过流敏感分析进行机会路径敏感分析,处理模糊的全局内存更新等。还包括在indirect-call分析中应用精度更高的分析算法。
作者在不同Android内核版本(谷歌、三星、华为)中的驱动模块上对SUTURE进行了评估。结果显示,我们的工具能够发现先前未知的高阶污点漏洞。到目前为止,SUTURE报告了79个真正的tru positive warning group,其中19个得到了开发人员的确认,包括一个被谷歌评定为高危漏洞。SUTURE的误报率相对来说也可以接受(51.23%),并且在性能方面也表现良好(例如,在30小时内并发分析目标内核的所有37个模块)。
2.Overview
2.1.Motivating Example
图1为一个高阶漏洞示例,其中 entry0、entry1、entry2 为3个不同的驱动程序entry function,其中连续调用 entry0、entry1 会触发2阶漏洞。触发过程如下:
-
首先,需要调用
entry0(),并传入cmd=0,这使得用户提供的user_input流入全局变量d.b[0]。 -
然后,需要调用另一个入口函数
entry1(),该函数随后调用了bar()。bar()函数获取了d.b[0]的值,该值之前由entry0()中用户输入设置,并且其地址与*(p+4)存在别名关系。 -
接下来,在
bar()函数中,对d.b[0]的值进行了一个溢出导致的加法操作(位于line 22)。
这个漏洞最tricky的特征是,原始用户输入到最终的溢出位置的污点传播过程涉及到全局变量 d,使其成为高阶(更具体地说,是2阶)taint-style漏洞。

检测高阶漏洞时,需要考虑不同 entry function之前的排列组合,比如这个示例中2阶污点分析需要遍历9种组合 (entry0 --> entry0、entry0 --> entry1 …),实际情况可能更复杂,同时污点分析的一些错误也更容易累积。潜在错误来源如下:
-
路径不敏感性:在line 3
cmd非零的情况下,entry0()可以将user_input传播到其调用者foo()中的d.b[1](line 13),然而实际上在line 6和line 12存在冲突的路径条件(cmd != 0和n == 0),这是不可能的。这样的路径不敏感最终可能导致一个误报,即在调用了entry0()后,entry2()的line 27可能导致溢出。 -
跨函数分析以及指针运算:为了发现line 22可能的溢出,静态分析算法必须能够准确解析指针算术并弄清楚
*(p+4)是d.b[0]的别名,否则就会产生误报。此外,为了弄清楚bar函数参数p的别名是d,分析还需要进行跨过程的分析。 -
索引不敏感(index-insensitivity):如果不区分
d.b[0]和d.b[1],那么分析调用序列entry0(cmd=0, ...) -> entry2()line 27可能会出现误报。如果与路径不敏感性结合在一起,那么在调用序列entry0(cmd=1, ...) -> entry2之后,line 27可能会有更多的误报,因为整个数组a可能被过度污染,而不仅仅是a[0]。此外,由于d包含d.b作为嵌套数组,分析还需要处理这样的嵌套结构。 -
分析算法还必须正确识别
entry1()中line 18清除了d.b[0]的taint tag,因此在第一次调用之后的其他entry1()调用将不再触发line 22的溢出。这需要一种cross entry的流敏感性。
2.2.Workflow
SUTURE的workflow如图2所示包括3个stage:
-
1.Input:SUTURE的输入包括目标驱动程序的llvm bitcode以及一个指定了entry function信息(例如,函数名称、用户可控制的参数)的配置文件。对于图1中的示例,配置文件中将列出
entry0()、entry1()和entry2()作为三个入口函数,其中entry0()的user_input参数被指定为用户可控制的输入。 -
2.Static Taint Analysis:接下来,SUTURE将进行静态污点分析,并为每个entry function生成独立的摘要,其中包括entry function对应的的所有local taint flow。在这个阶段,用户输入和全局变量都被视为污点源,同时记录了entry function中每个sink变量的local taint flow。在图1中,作者在左下角的方框中展示了三个entry function的local taint flow。值得注意的是,SUTURE以一种无关顺序的方式仅对每个entry function进行一次分析,例如,
entry0()可以在entry1()之前或之后进行分析,避免了在不同的调用序列中重复分析相同entry function的昂贵成本,然而,SUTURE仍然能够发现后面详细介绍的高阶漏洞。(注:这里的local taint flow并不是单个function内,依旧是跨函数的,只是在单个entry function的scope内,不同entry function对应的local taint flow主要依靠全局变量连接) -
3.Vulnerability Detection:在这个阶段,SUTURE尝试针对各个cross entry function进行漏洞检测。对于找到的bug-inducing statement,SUTURE将分析是否存在从用户输入到bug-inducing statement的cross entry taint flow。在motivating example中,
entry0()和entry1()的local taint flow被组合在一起形成最终漏洞的高阶taint flow。 -
4.Output:对于每个告警,SUTURE输出与告警类型和完整的cross entry taint flow等相关的信息,SUTURE还计算每个告警的阶数。对于motivating example,SUTURE最终触发一个有效的告警,其调用序列显示在右下角(一个二阶漏洞)为
entry0 --> entry1,同时避免了误报。

3.Static Analysis Design
3.1.Positioning
静态污点分析的目标是为每个entry function构建一个污点摘要,为了实现这个目标,SUTURE独立分析每个entry function并记录其taint fact。其静态污点分析沿用了Dr.Checker的大部分,包括指针分析和污点分析的tranlation function,Dr. Checker以自上而下的方式对每个entry function进行了完备的过程遍历,对于每个访问的LLVM IR,进行别名和污点分析,更新与IR中涉及的变量相关联的point to和taint信息。基本上,Dr. Checker的静态分析是上下文敏感、流敏感和字段敏感的。然而,所有这些敏感性都是部分或有限的,这在SUTURE中需要进行处理。此外,与Dr. Checker相比,SUTURE对静态分析还有许多额外的要求。
3.2.Definitions
-
Def 0-entry function ϵ \epsilon ϵ:内核模块的入口函数充当模块接口的一部分,因此在同一模块内它没有任何调用者,并且应当由用户或其他模块(例如驱动程序的顶层
ioctl()函数)直接调用。 -
Def 1-taint source S S S: S S S 包括入口函数的由用户提供的参数( U U U,比如图1
entry0的user_input)以及所有全局变量或内存区域(作者称之为全局内存, G G G,比如图1的d)。注意, G G G 包括显式定义的全局变量(例如,全局整数)以及从它们可达的变量,例如,包含指向堆内存的指针字段的全局结构体变量。因此 S = U ∪ G S = U \cup G S=U∪G -
Def 2-calling context △ \triangle △: △ = [ i 0 , i 1 , . . . , i 2 n ] \triangle = [i_0, i_1, ..., i_{2n}] △=[i0,i1
SUTURE:高阶污点漏洞检测工具

本文介绍了SUTURE,它是对Dr.Checker检测高阶漏洞的改进。该工具可解决高阶漏洞检测的性能和精度问题,通过独立分析每个entry function生成摘要,按需构建高阶污点传播路径。在不同Android内核版本驱动模块评估中,能发现未知高阶污点漏洞,误报率可接受,性能表现良好。
最低0.47元/天 解锁文章
1376

被折叠的 条评论
为什么被折叠?



