TChecker: Precise Static Inter-Procedural Analysis for Detecting Taint-Style Vulnerabilities in PHP Applications
香港中文大学,CCS2022
Abstract
由于php语言的高度复杂性,现有的污点分析解决方案由于其不全面的程序间分析和各种实现问题,存在着高假阳性和高假阴性的问题,即实现精确的静态污点分析是很困难的。
作者在这项工作中提出TChecker,一个上下文敏感的程序间静态污点分析工具,用于检测php应用程序中的污点式漏洞,它对php的类迭代进行程序间数据流分析,以细化类的类型,从而可以精确的识别调用目标,并且实现了php的一些动态特性,包括动态包涵。
发现了18个0day,明显优于其他的一些最新工具。
Introduction
php是当下最流行的服务端语言,约有78%的网站使用它,php会对用户的互动和请求作出反应,例如用户的点击,这种交互模式为各种攻击提供了巨大的空间,尤其是污点式漏洞,当用户的输入数据没有被完全过滤时,就会出现这一类漏洞。
现在已经提出多种方法来检测在野的污点式漏洞,一般可以分为动态方法和静态方法,动态方法注入攻击有效载荷,并在部署的网络应用程序中检查相应的输出,然而动态方法的代码覆盖较为有限,并且受高假阴性的影响,且具备较低的扩展性,另一方面,污点分析则是完全自动化和可扩展的,可以实现较高的代码覆盖率,因此静态分析已经被广泛采用,并在检测污点式漏洞方面展现出巨大前景。
作者在现有解决方案中发现了3个固有的限制:
- 之前的污点分析并不是对环境敏感的,现代php应用程序中很多污点式漏洞都存在上下文相关性,只有在特定环境下调用相应的函数或方法才会表现出来。具体来说,找到目标方法的调用函数需要确定接收对象的类,例如($obj in $obj -> f());这是非常有挑战的,因为php是动态类型的语言,接收对象的定义并没有具体的类型注解,作为结果,php对象的类型在运行前很难决定。常用的寻找目标函数的方法是将被调用的函数/方法名与函数定义相匹配,这种方法要么会导致过度污染,要么会导致污染不足;
- 其次,因为静态分析php代码的困难,现存的工具在简化污点分析时,设定了一些假设,但这些假设可能并不总是成立,如商业工具RIPS-A假设php应用的调用栈总是调用同一个目标函数,然而php应用可以在不同的调用上下文中调用不同的函数。其他的开源污点分析工具也作出了一些强有力的假设,比如如果任何一个参数是污点,那么调用栈的返回值就是污点,这种简化会导致不精确的污点分析,从而引入假阳性和假阴性
- 最后,现有的工具不支持PHP常用的高级特性,比如动态常量,constant( c o n ) 等 , 可 变 变 量 con)等,可变变量 con)等,可变变量$a等,对这些特征建模失败会导致数据流分析等提前终止,从而造成错误的否定。
作者为了解决相应局限性,开发一个精确的静态程序间污点分析。
TChecker用几种新技术克服了上述挑战。具体来说,它对PHP对象反复进行程序间数据流分析,以推断其类型或值。这有助于它精确地确定方法调用的调用目标,以逐步建立一个精确的调用图,这对程序间数据流分析进一步有利。
此外,由于一个调用点可能在不同的上下文中调用不同的被调用函数,TChecker以一种对上下文敏感的方式分析调用点。它不总是把所有可能的目标函数看作是一个调用站点的目标函数,而是根据调用上下文确定目标函数,并把污点传播给正确的目标函数。
对复杂和常见的PHP特性进行建模,并解决了PHP应用程序污点分析中的几个实施难题。具体来说,TChecker跟踪对象属性中的污点,分析一些常用的动态特征,如动态包含,并对PHP内置函数的语义进行编码等等。这将使TChecker能够全面地跟踪复杂的PHP应用程序中的污点传播。
7.3万行的Java代码实现了TChecker的原型。并在17个有代表性的PHP应用程序的数据集上彻底评估了TChecker。TChecker在数据集中检测到131个真正的阳性污点式漏洞,包括18个以前未知的漏洞。
与最先进的工具的比较进一步表明,TChecker明显优于它们,多检测了50个漏洞。TChecker还可以找到现有工具检测到的所有漏洞,而且精度比较高。我们对这18个新的漏洞进行了定性,发现它们有可能被利用,造成严重的安全后果。例如,osCommerce2(v2.3.4.1)的一个新的XSS漏洞可能允许无权限的攻击者破坏受害者的用户账户。
https://github.com/cuhk-seclab/TChecker
Background
php特性
- 方法调用;$o->f()
- 变量函数;$f = “eval”; $f()
- 动态包含;require $a
- 对象属性;$obj->prop
php程序分析
- 调用关系分析,分析调用关系是程序间分析的先决条件;
- 数据流分析;
污点式漏洞
定义:网络应用程序通常为终端用户提供许多功能,并相应地对用户的输入和互动采取行动,例如,表单提交或点击。当用户提供的数据(即污点)没有得到充分的净化,并被用于应用程序的关键操作(即sink)时,就会出现安全漏洞。这样的漏洞被称为污点式漏洞[26]。常见的污点式漏洞有XSS,SQL注入等。
污点分析
污点分析跟踪来自外部的污点(例如不受信任的用户提供的数据)在程序执行过程中的传播,检查污点数据是否以流向程序的关键位置,即sink,最后报告有可能被攻击者操纵的sink。
sink:污点汇聚点,代表直接产生安全敏感操作(违反数据完整性)或者泄露隐私数据到外界(违反数据保密性
现有静态污点分析的解决方案有以下的关键思想:
- 函数名匹配:分析调用关系对于跟踪函数便捷传播的污点是必要的,为了解决确定方法调用目标的挑战,一种常见的方法是忽略调用的对象,只匹配被调用的方法名称,RIPS将被调用的方法名f()与整个php程序中的函数定义进行比较,将匹配的函数视为调用对象obj->f()的目标函数,这种方法存在较多的误报;
- 数据流分析:RIPS的专有版本可以对php程序进行数据流分析,RIPS可以通过程序内的数据流分析推断一个对象的类型,然后确定方法调用的目标函数,并且还对一些函数名变量进行同样的分析,例如$a(),但由于缺乏程序间分析,RIPS无法推断出在其他函数作用域中分配的变量的类型或值;
- 函数摘要:为了避免重复分析,创建函数摘要总结一个函数中的数据流,因为一个函数可能包含调用栈点,之前的工作假设每个调用栈点在任何调用上下文中都调用相同的函数。使用函数摘要可以大大提高分析的效率,因为每个函数只分析一次,无需重复分析多次,为性能牺牲了分析的精确性。
Motivating Example
IMG标签中的src属性被定义为base_url函数的一个返回值,用户控制输入的_POST被用作该函数调用的参数,在没有消毒的情况下被输出,攻击者可以通过制作有效载荷进行xss攻击。
污点分析为了检测这样的漏洞,应该分析第2,5,13和17行,最后返回第2行的返回值。
为了确定第5行的get_instance()这个调用栈的目标函数,需要推断出接收对象get_instance()->config()的类型,为此需要进行数据流分析,找到它可以被实例化的类,然后推断出所有调用第3行base_url()的函数,因为该对象可以在不同的调用上下文中被实例化,然而只有完成所有的调用关系分析后才能确定base_url的调用者,但情况并非如此,因为当前还在寻找第5行调用栈的目标函数。
Overview
- 进行程序间污点分析是重要的,主要挑战则是调用关系的分析,为此,首先建立一个调用图
- 这有助于它以后在函数调用中进行更准确的污点传播。在传播污点之前建立调用图的好处是双重的。首先,调用图的建立已经包含了一个调用站点的所有可能的目标函数,而且是以一种与环境相关的方式。因此,给定一个特定的调用环境,TChecker可以直接从可能的目标函数中选择一个调用站点的正确目标函数。这种选择是一个从调用上下文到目标函数的映射过程,它使TChecker能够有效地获得目标函数。如果不事先构建调用图,TChecker就必须在污点分析中每次遇到(甚至在同一上下文中)调用点时重复推断其调用目标。
- 其次,调用图允许TChecker进行有选择的污点分析。例如,如果一个调用点的所有目标函数都不使用任何污点变量,TChecker可以跳过对该调用点的污点分析。这可以避免对不相关的函数进行不必要的分析,从而提高整体分析效率。
- 然后执行对上下文敏感的程序间污点分析来识别漏洞。
具体来说,TChecker采取两个阶段来增量构建一个调用图。在第一阶段,TChecker对接收对象和变量函数名进行反向数据流分析,以找到每个调用点的函数名(§4.2.1)。在第二阶段,它将一个调用站点连接到它的调用目标。更重要的是,TChecker迭代地执行这两个步骤。通过向调用图添加新的调用目标函数(在新的上下文中),可以发现新的数据流关系,使TChecker能够根据新的数据流关系确定更多函数名称变量的值或更多接收对象的类,然后进一步找到相应的新调用目标。
第3行的base_url()函数被应用程序中的多个调用站点调用。当TChecker从第2行的调用站点连接一个新的调用边到第3行的函数定义时,它检查新引入的调用函数(即通过新连接的调用边到达base_url()函数节点的所有函数节点)是否包含对get_instance()->config的赋值。如果在函数p()中存在这样的赋值,TChecker会从函数p()开始对get_instance()->config进行逆向数据流分析,以推断其类型。然后,TChecker在第4行更新调用站点get_instance()->config->base_url()的目标函数。
Implementation
作者用php-ast将PHP源代码解析为AST,并使用PHPJoern构建控制流图(CFG)和数据依赖图(DDG),用于程序内数据流分析。原始的DDG不能区分不同的对象属性(例如 o b j − > p 1 和 obj->p1和 obj−>p1和obj->p2)。为了解决这个问题,TChecker额外使用属性名称(如p1和p2)来识别对象属性。