SUTURE: 内核高阶污点漏洞检测

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

作者来自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为一个高阶漏洞示例,其中 entry0entry1entry2 为3个不同的驱动程序entry function,其中连续调用 entry0entry1 会触发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 --> entry0entry0 --> entry1 …),实际情况可能更复杂,同时污点分析的一些错误也更容易累积。潜在错误来源如下:

  • 路径不敏感性:在line 3 cmd 非零的情况下,entry0() 可以将 user_input 传播到其调用者 foo() 中的 d.b[1](line 13),然而实际上在line 6和line 12存在冲突的路径条件(cmd != 0n == 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 entry0user_input)以及所有全局变量或内存区域(作者称之为全局内存, G G G,比如图1的 d)。注意, G G G 包括显式定义的全局变量(例如,全局整数)以及从它们可达的变量,例如,包含指向堆内存的指针字段的全局结构体变量。因此 S = U ∪ G S = U \cup G S=UG

  • Def 2-calling context △ \triangle △ = [ i 0 , i 1 , . . . , i 2 n ] \triangle = [i_0, i_1, ..., i_{2n}] =[i0,i1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值