NAVEX->Precise and Scalable Exploit Generation for Dynamic Web Applications
出处:27th USENIX Security Symposium
作者:Abeer Alhuzali, Rigel Gjomemo, Birhanu Eshete, and V.N.
单位:Venkatakrishnan University of Illinois at Chicago
资料:Paper | Github
1. Abstract & Introduction
作者在本文中提出了一种以静态分析作为指导,结合动态分析自动验证漏洞并构造可用exploit的工具NAVEX。
研究问题:
- 解决以往自动化审计的误报以及必须结合人工参与构造Exp的问题;
- 静态分析虽然覆盖率高,但是对于具有动态特性的语言其建模困难。
解决方案:
- 静态分析阶段:使用符号执行创建Web应用程序的各个模块的行为模型。标记出包含潜在漏洞点的模块;
- 动态分析阶段:使用Web爬虫和concolic执行器去发现可能导致攻击者进入易受攻击模块的可能的HTTP导航路径,之后使用约束求解器生成一组对漏洞进行利用的HTTP输入序列。
方案优点:
- 动态分析与静态分析相结合提升了性能,可以应用于大型应用程序;
- 是一种多类型漏洞的Exp生成框架。
NAVEX分析了320万行PHP代码,自动构建并利用204个漏洞,其中有195个与SQLI和XSS相关,而9个与逻辑漏洞相关。此外NAVEX是第一个可以自动发现并利用EAR漏洞的方案。
2 Challenges and Approach Overview
2.1 Running Example
下面是一个包含漏洞的小型Web程序。selectBooks.php模块在第23-38行使用了Web表单来实现选择数据,其中在23行调用了JavaScript来验证数输入,相关定义在第31-36行。第4-12行实现用户输入由服务器端代码进一步验证和过滤。之后第17行通过MySQL查询来验证书籍的可用性。最后根据查询结果,初始化$_SESSION['ISBN']
并在浏览器上打印到hold.php的HTTP链接。
之后跳转到hold.php执行附加检查,如果满足,则HTTP链接引导用户进入下一步(第7行)。 单击链接时,将设置超全局$_GET ['step']
,从而让hold.php包含模块checkout.php并执行。
checkout.php通过向用户提供链接(第19行)进行确认来完成借用过程。 该链接设置两个超全局变量($_GET['step']
和$_GET['msg']
),将在第6行进行检验。最后,调用确认功能(第13行)以通知用户该书已成功保留。
该程序存在以下几点缺陷:
- selectBooks.php:17中$publisher经过简单校验就传入SQL语句进行拼接,可造成SQLi漏洞(str_place函数进行了无效过滤);
- checkout.php:15行使用了echo,可能会造成XSS;
- selectBooks.php:3行调用header但是没有使用exit(),造成EAR漏洞进而可以在不进行登录的情况下触发下面的SQLi漏洞。
2.2 Challenges
面临的挑战主要是以下三点:
- 污点可达性:对于WebApp而言,完成一个功能往往是各模块相关联的。此外,模块中往往还使用内置函数过滤(比如htmlspecialchars)、隐式过滤(比如类型转换)、自定义过滤和数据库约束条件带来的过滤来消除风险。所以攻击路径的寻找是具有一定难度的。
- 动态特征:静态分析对于动态程序的分析具有局限性,比如无法推断动态将会生成怎样的表单或者链接(比如使用JavaScript来生成的内容)。
- 扩展性:对大型程序的分析会覆盖客户端,服务器端和数据库后端,因而会产生很多路径,必须使用一些方法来减少一些无用的路径。(之所以叫扩展性应该是跟后面的COG图的扩展有关)
2.3 Approach Overview
方法主要分为两个步骤:
- 可能的漏洞点识别。首先,定位程序中可能的漏洞点以及对应的模块(这样减少后面的搜索空间);其次,对各种过滤方案进行了精确表示;最后,对自定义的过滤先使用符号约束构建模型之后使用约束求解器来判断过滤的稳健性。
- 具体的漏洞利用生成。首先,动态执行得到Web应用程序的导航结构;其次,结合静态分析得到的漏洞点和对应的模块寻找可行的攻击路径;最后,多次重复动态执行,使用约束求解最大化路径覆盖。
3 Architecture and Algorithms
3.1 Vulnerable Sink Identification
目的:排除那些不包含漏洞点的模块
方法:如下图,首先,构建每个模块代码的图模型;然后,发现包含源和目标(漏洞点)之间数据流的路径;最后,使用符号执行生成公式后利用约束求解以确定哪些路径可能被利用。
3.1.1 Attack Dictionary
多种漏洞被触发的过程是相似的–均是攻击载荷到达敏感接收器进而触发漏洞,所以NAVEX使用这种相似性构建了一个包含Sinks(敏感接收器)、Sanitizations(过滤函数)、遍历类型(前向遍历还是反向遍历)和攻击字符串(其实就是收集的WebFuzz字典)的攻击字典来实例化针对每类漏洞的分析。
字典包含:SQLI,XSS,文件包含,命令注入,代码执行和EAR漏洞。
3.1.2 Graph Construction
代码属性图(CPG)是一种结合了抽象语法树(AST),控制流图(CFG),调用图和数据依赖图(DDG)的表示。此处,将过滤标签和数据库约束标记作为属性添加到CPG,从而对其进行扩展。最终将漏洞发现问题转变为对CPG图的遍历问题。
3.1.3 Graph Traversal
此步骤的目的是通过对扩展后CPG来寻找攻击路径,主要分为向后遍历和向前遍历。向后遍历的算法如下图所示。正向遍历则主要是从源到可能漏洞点的路径搜索,这种搜索方式也是对EAR漏洞的重要检测方法。(文中提到了良性EAR–header之后不含可利用点和恶性EAR–header之后包含可利用点)。图遍历最终将会返回一组可能容易受到攻击的路径供下一步使用。
3.1.4 Exploit String Generation
利用上一步发现的攻击路径来生成攻击字符串是静态分析的最后一步。首选构造增广公式 Fpath∧Fdb∧Fattack(Fpath是易受攻击的路径;Fdb是从DB标记派生的约束;Fattack是针对漏洞点的可控变量的,其值来源于之前构造的攻击字典)。之后使用求解器求出一组解(解就是是攻击字符串传入可控变量后在易受攻击的路径上经过过滤到达漏洞点依旧可以造成危害)。到此静态分析过程结束,之后的过程是通过动态分析得到攻击字符串到达攻击点的HTTP请求序列。
3.2 Concrete Exploit Generation
NAVEX执行几个步骤来生成具体的Exp,如下图所示。首先,创建导航图来发现所有执行应用程序模块的可能HTTP请求序列;之后,结合静态分析阶段得到的可能漏洞点来筛选对应模块的执行路径;最终,生成可用的Exp。
3.2.1 Dynamic Execution
NAVEX使用动态执行方法,借助约束求解和concolic执行来生成大量表单输入,以帮助爬虫最大化应用程序的覆盖范围。
爬虫(解决客户端约束条件):使用种子URL启动,可以对Web站点的每个角色自动化登录验证,采用广度优先遍历算法,新抓取的URL将作为下一次的爬虫的起始。此处的优点在于,首先,爬虫可以构造符合JavaScript验证的输入;其次,有效表单输入的自动生成提高了覆盖范围。
自动有效输入构造:NAVEX结合了表单HTML约束Fhtml和JavaScript约束Fjs来生成最终形式约束Fform,之后使用求解器来求解,最终得到对应的HTTP请求。示例如下:
1 | // 约束公式 |
解决服务器端约束:在服务端也会对输入有一定的约束,所以在满足前端约束后必须判断服务端约束是否也同时得到了满足。为解决这个问题,NAVEX会动态跟踪判断信息是否满足服务端约束,主要根据以下两点信息:(i)更改其状态(即,创建新会话,设置新变量和超全局值等);(ii)执行敏感操作来确定请求是否成功,比如查询数据库等。如果检测到请求没有成功执行,那么将会concolic执行依据服务端程序逻辑得出约束公式并对之前发现的执行路径进行更新,之后使用求解器求解生成新的表单数据进行提交(在成功之前会一直执行这个过程)。服务端约束示例如下:
1 | (book name=="intro to CS by author1" ∨ book name=="intro to Math by author2") ∧ length(publisher)<=35 ∧ edition >0 |
PS:NAVEX会存储导致成功提交的完整HTTP请求。
3.2.2 Navigation Graph
导航图是一个有向图G=(N,E),其中每个节点n∈N表示HTTP请求.每个边e=(ni,nj)∈E表示从ni到nj的导航,表示发起d的请求,可以是链接形式。图中的每个节点都具有以下属性id,URL,role和form params,用于表示表单提交生成的HTTP请求。id属性存储节点的唯一标识符,URL属性是HTTP请求中的URL,它由请求的模块名称和HTTP参数组成,role属性包含爬虫使用的登录凭证。示例图如下:
3.2.3 Final Exploit Generation
静态分析:扩展的CPG图和Exp字符串。
动态分析:NG导航图。
如何将这个两个信息进行组合并产生Exp就是此步的作用。
优点:将漏洞Exp的构造问题转换为对图的简单搜索问题。
难点:文件被包含这个过程在NG中是看不到的。
难点解决:预处理包含解析,此步骤创建存储文件包含关系的包含映射。通过执行遍历来构造映射,该遍历在增强的CPG中搜索表示对文件包含PHP函数的调用的节点,最终将得到包含图。
之后使用NG和包含图来搜索公共模块到存在漏洞模块的路径,具体算法见下图:
依据Figure4我们使用算法得到的序列如下:
1 | 1. http://localhost/App/index.php |
4 Implementation
NAVEX基于现有的几种工具进行实现:
- 扩展的CPG图利用phpjoern进行实现;
- 扩展的CPG图存储在Neo4j图形数据库中;
- 图遍历算法使用Apache TinkerPop编写;
- 约束求解使用z3以及其扩展Z3-str;
- 爬虫程序使用被约束和z3断言扩展的crawler4j;
- 爬虫对JavaScript的处理使用了Narcissus JavaScript引擎的扩展;
- 服务端代码执行跟踪使用Xdebug。
5 Evaluation
数据集:26个真实PHP应用程序,代码库组合为3.2M SLOC和22.7K PHP文件如下表所示。
标准:
(i) 评估最流行应用的最新版本,并且要求是复杂且大型的PHP应用程序,如Joomla,HotCRP和WordPress;
(ii) 使用NAVEX与已有的一些先进项目(例如,Chainsaw,RIPS)进行比较。
部署:实验环境:Ubuntu 12.04 LTS VM,2核2.4GHz,40GB RAM。目标WebApp部署:(1)进行静态分析;(2)部署后进行动态分析(注意每次爬虫后要恢复数据库初始状态)
结果摘要。 NAVEX共构建了204个漏洞exp,其中195个注入类型,9个是逻辑漏洞。 增强的CPG平均将假阳性(FP)减少了87%。包含用于构建导航图的客户端代码分析将Exp生成的精度平均提高了54%。 在评估集上,NAVEX能够进行6个HTTP请求来拼接出Exp。
增强的代码属性图统计:表2显示了增强的CPG构建时间和大小,可以看出NAVEX的运行时开销很低。
导航图统计:表3总结了在NAVEX的步骤II中生成漏洞Exp的总时间。
以上是综述,下面将阐述作者从四个方面对NAVEX的评估:1.Exploits;2.定量分析;3.与相关工作的比较;4.限制和讨论
5.1 Exploits
接下来作者将对NAVEX针对的漏洞逐一简要说明:
SQLI漏洞:
漏洞触发点:mssql_query, mysql_query, mysqli_query,sqlite_query
漏洞定位:155个SQLI可利用的漏洞点,其运行时间为37分和45秒。
Exp生成:105个SQLI漏洞利用Exp,其运行时间为7分和76秒。
SQLI漏洞利用:
XSS漏洞:
漏洞触发点:echo、print
漏洞定位:1小时49分钟内共发现了133个XSS可利用的漏洞点,其中5个是误报
Exp生成:40分12秒为133个漏洞点生成了90个XSS漏洞利用
XSS漏洞利用:如下所示包含strtr函数的路径会被认为是可被攻击的,但是htmlspecialchars的就不会,因为strtr函数对XSS的过滤能力很弱,之后求解器会选择%26%2339%3B-alert(1)-%26%2339%3B来进行绕过。
EAR漏洞:
漏洞触发点:header
漏洞定位:17分17秒内发现了19个良性EAR和3个恶意EAR漏洞
Exp生成:成功针对22个EAR漏洞生成了9个漏洞利用
代码执行漏洞:
漏洞触发点:eval
漏洞定位:在21m20sec内找到98次调用但是均无安全缺陷
命令注入漏洞:
漏洞触发点:exec,expect_popen,passthru,pcntl_exec,popen,proc_open,shell_exec,system,mail,backtick_operator
漏洞定位:在22m32sec内NAVEX没有找到任何易受影响的漏洞点
文件包含漏洞:
漏洞触发点:include,include_once,require,require_once
漏洞定位:在27分58秒内找到1处接收器内包含了可控变量但是因为后面有约束所以无法构造出Exp,即此处依旧不可利用
5.2 Measurements
图5显示了NAVEX的性能(定位漏洞点的耗时和构造Exp的耗时)
图6显示使用了过滤和DB标签增强的CPG对可能漏洞点判别的影响。(减少了误报)
- 总覆盖率为68%
- 对客户端代码进行分析带来的好处:提升了精度和覆盖率
5.3 Comparison with Related Work
漏洞检测方面与RIPS,Chainsaw的对比;
Exp生成与Chainsaw(只能够对SQLi和XSS生成Exp)的对比;
效率方面与Chainsaw的对比:
生成Exp: NAVEX->25分钟2秒;Chainsaw->112分钟
前期准备: NAVEX->18分26秒;Chainsaw->1天13小时21分
5.4 Limitations and Discussion
- Web应用程序的某些功能尚不受支持,比如文件上传逻辑;
- 自动从图节点导出的TAC公式不完整(未提及哪些不支持);
- 静态分析进行漏洞定位存在误报;
- CPG图不支持解析动态函数调用(文中说这个不太重要但未具体说明,可能是使用极少);
- 如果网站的动态逻辑不被NAVEX支持,那么将无法构造漏洞利用(比如前面的SchoolMate程序的会话维持未被支持<-笔者从文中得到的信息)
6 Related Work
详细见论文中表述
7 Conclusions
PS: 此部分是一些笔者个人的总结并非论文的最终总结
之前对PHP漏洞的自动化审计工作主要分为静态分析和动态分析。其中静态分析的一些代表的可实际使用的工具有rips、cobra、Cobra-W以及seay代码审计系统,其中rips的建模分析以及攻击字典的构造是比较详细和全面的。虽然可以参考其代码和论文进行学习,但是开源版对现在而言已经不具有实用价值。cobra是基于AST进行分析,AST是具有一定的局限性的,从分析效果上而言没有控制流图好,当然也没有今天提到的CPG好。但是cobra在AST上建立的分析模型以及他对规则集的引入方式是具有一定参考性的。当然在cobra之后的Cobra-W是令人眼前一亮的感觉,虽然还未完全开发完成,但是它对文件包含的处理以及对于自定义过滤函数的处理思想是很值得学习的(相比rips的暴力直接将代码拼接好一些)。seay代码审计系统的优点就是其中包含了对数据库的审计。其它的还有phpvulhunter等工具,但是年代较为久远因而笔者没有对其代码做进一步的分析。在分析过上面的程序之后笔者也曾在一年前尝试引入别名分析等新机制来进一步改善静态分析的准确率,但是效果不是很理想随后就弃坑了。动态分析最具代表性的是prvd,这个笔者还未进行分析,但是用效果不错,感兴趣可以对其进行进一步的分析。
最后回到本文,此文提出的NAVEX采用静态分析和动态分析相结合的方式,可以自动完成对漏洞的分析并生成Exp。在文中提到的几个方法都是非常新颖的,从效果上来看很不错。如果从工程的角度来看,完全可以借鉴其思想从而进行深入的开发完善。