当前位置: 首页 > > 天 方 夜 “谈” 第11期 | Pangr:基于行为的自动漏洞检测和利用框架

天 方 夜 “谈” 第11期 | Pangr:基于行为的自动漏洞检测和利用框架

发表于:2020-03-18 20:47 作者: 方滨兴班 阅读数(8281人)

Pangr: A Behavior-based Automatic Vulnerability Detection and Exploitation Framework

 

内容来源:2018 17th IEEE International Conference On Trust,Security And Privacy In Computing And Communications/12th IEEE InternationalConference On Big Data Science And Engineering

第一作者:Danjun Liu

文章地址:https://ieeexplore.ieee.org/document/8455971

Ⅰ.  问题介绍

   

2010年,Stuxnet在全球范围内感染了超过45,000个网络。2017年,WannaCry勒索软件利用NSA泄漏漏洞“EternalBlue”的风险传播到全球至少150个国家,超过100,000台机器被感染。这些事件的爆发揭示了网络威胁的逐渐出现。随着机器学习和大数据处理技术的发展和普及,人工智能的研究和应用进入了一个新的高潮。人工智能的优势在于它们能够比人类更快地找到并修复漏洞,以更低的成本提高系统和应用程序的安全性,从而显著提高网络防御的灵活性。


如今,随着软件规模和复杂性的迅速增加,漏洞变得多样化,难以识别。通过手动构建的方式来检测和利用漏洞是不切实际的。因此,一种有效的自动检测和利用软件漏洞的方法是迫切需要的。本文实现了一个自动漏洞检测、利用和修补的系统——Pangr。Pangr采用angr的符号执行技术模拟漏洞行为,并基于其触发行为构建完整的漏洞模型,以识别漏洞并生成exp或漏洞利用方案。Pangr与AEG、APEG、Mayhem、PolyAEG等工具最大的不同就是Pangr不仅能够利用堆溢出漏洞,而且可以为软件漏洞点生成相应的保护方案。

知识介绍:angr是一个二进制代码分析工具,可以自动分析二进制文件。查找和利用漏洞的主要挑战是难以在二进制代码中可视化数据结构和控制流的信息。angr是一个基于python的二进制漏洞分析框架,它集成了各种现有的分析技术(例如,KLEE和Mayhem),它通过加载和分析二进制文件来执行二进制和系统状态模拟。这些技术包括静态分析(控制流图,价值流图,后向切片等),动态分析(符号执行,调试)和约束求解。

Ⅱ. 框架概述

Pangr由五个部分组成。如图1所示,在获得输入的二进制文件后,崩溃引擎会测试二进制文件并找到可能导致程序崩溃的新输入,然后将崩溃数据发送到测试引擎和漏洞分析器以检查其有效性并执行进一步分析。初始化程序在符号执行之前预处理二进制文件。然后,漏洞分析器使用符号执行来检测基于预处理信息的可利用漏洞。如果发现可利用的漏洞,它将被发送到漏洞利用器以生成exp。完成该过程后,防御引擎会生成防御规则或二进制补丁。

图片.png

图1 Pangr的整体框架

Ⅲ. 自动漏洞检测

漏洞自动检测阶段涉及崩溃引擎、初始化器和漏洞分析器三个引擎。崩溃引擎负责二进制模糊测试,如果发现崩溃,它将被发送到漏洞分析器进行进一步分析并发送到测试引擎进行测试。初始化模块负责一些初始化工作,例如功能识别和功能挂钩工作。漏洞分析器将进一步检测和分析漏洞。

A 崩溃引擎


崩溃引擎基于AFL模糊器和符号跟踪器angr使用符号执行辅助模糊测试(参照Driller)。通过监视AFL执行,Driller可以决定何时开始对AFL生成的特定输入进行符号跟踪,当AFL在一轮输入变异后未能找到新的状态转换时,它会调用angr执行符号执行,跟踪AFL提供的特定输入。每当遇到条件指令(如cmp)时,可能会有新的分支,如果AFL不知道新分支,它将调用SMT求解器生成可以到达新路径的输入并将输入反馈给AFL,然后继续进行模糊测试。模糊测试的缺点是通常只探索浅路径,因为AFL的许多生成输入根本无法通过条件指令的检查。符号辅助模糊测试利用了对语义理解的符号执行,以及模糊测试的短执行时间。

B 初始化器


初始化器主要负责在符号执行之前准备符号。符号执行的最大问题是路径爆炸。在二进制文件中,随着程序的执行,程序会遇到很多分支指令,导致分支爆炸式增加,angr的符号执行将执行每个分支。如果分支太多,则消耗的时间将增加,并且内存将很快耗尽以保持每个分支的状态。Pangr为每个函数计算CRC16校验和,然后比较两个函数的CRC值以确定它们是否是相同的功能,这种方法可以解决搜索量大的问题。另外,这种方式能够尽可能的避免探索不相关的代码,例如链接库中的代码。

C 漏洞分析器


Pangr分别对格式字符串、堆栈溢出和堆溢出漏洞的行为进行建模,并利用符号执行期间漏洞触发的内在语义来发现有价值的漏洞。漏洞分析器在找到易受攻击的点后,有利于以后的漏洞利用,漏洞分析器记录输入值和上下文信息,如寄存器,堆栈,堆和环境变量等。


1)格式字符串漏洞


格式字符串漏洞通常出现在以下类型的函数中:

表1 可能导致格式化串行漏洞的函数

图片.png

格式参数受输入值影响后,攻击者可以控制格式参数,这意味着目标二进制文件包含格式字符串漏洞。根据编译规则的特点,通用格式参数是在编写程序时已经确定的值,它存储在.data和.bss等二进制部分中,因此它位于程序自己的地址空间中,而用户的输入通常位于栈或堆中,栈和堆空间地址超出了程序本身的范围。因此,在32位x86系统中,首先生成数据依赖图,然后仅在程序执行到可疑库函数时检查堆栈上的相应格式参数。如果format参数受输入影响,则可以将二进制判断为格式字符串漏洞,此时记录上下文信息。

2)栈溢出漏洞


栈溢出是栈缓冲区溢出引起的一种漏洞,这可能导致数据覆盖或执行流程劫持。如清单1所示,main()函数输入一个长度大于20的字符串,然后调用vul()函数,str字符串溢出到buf缓冲区。


图片.png

清单1 栈溢出漏洞

栈结构如图2所示。无论采用何种方式,栈溢出的最终结果是使ip指针指向用户可控制的地址。所以在符号执行期间,一旦Pangr发现ip受输入影响,它很可能是栈溢出漏洞。另外,格式化字符串和栈溢出漏洞不能直接劫持程序控制流程,所以Pangr还记录了上下文信息。


图片.png

图2 栈结构


3)堆溢出漏洞


堆溢出是一种由堆缓冲区溢出引起的漏洞。因为它不会导致崩溃,所以很难检测到。这可能会导致覆盖下一个堆的内容或堆结构。这种类型的漏洞很难被发现,因为它不能直接导致崩溃,触发它的条件要复杂得多。如清单2所示,main()函数首先分配一个堆块,然后调用get_str()函数将数据读取到堆块,显然如果请求的堆块只有8个字节,则将长度为0x1f的输入复制到堆块,从而导致溢出。


Pangr的策略是,在符号执行过程中,一旦遇到调用malloc()函数的程序点,它就会将堆块和大小的地址记录到GlobalChunkArr数组中。就像malloc(num)一样,如果num是某个值,那么它可以直接记录。如果num是受污染的值(受输入值影响),Pangr使用SMT求解器计算最小值并记录它。然后它继续符号执行。如果存在写入globalChunkArr数组中记录的块的指令,则可能是字符串复制操作。字符串复制操作通常由库函数或循环实现,如清单2所示。这些库函数包括read,strcpy,memcpy,sprint,snprintf等。在复制过程中,一旦Pangr发现跨越块边界的访问,Pangr将其视为堆溢出漏洞


图片.png

清单2 堆溢出漏洞


Ⅳ. 自动漏洞利用

漏洞利用程序中使用的方法分为三种。文章中仅讨论了更一般的方法。

A 格式字符串漏洞利用


格式字符串漏洞主要基于格式字符串的三个特征。一种是使用“%s”从目标存储器地址读取数据。第二种是使用宽度修饰符“$”来控制输出的字符数。第三种是使用“%n”将输出字符数写入目标存储器地址。例如,“%8$s”可以读取堆栈上第八个参数指向的地址的值。

B 栈溢出漏洞利用


有两种方法可以利用堆栈溢出漏洞,一种是使用ShellCode,另一种是构造ROP链。ShellCode构建存在两个问题。一个是堆栈可能包含重要数据,一旦被覆盖则会发生引用错误,如清单1所示,如果strcpy()导致ptr被覆盖,则在vul()函数返回之前将发生指针引用错误,因此,我们无法成功劫持控制流。第二个问题是堆栈空间不足以放下整个ShellCode,如图2所示,buf和ret_addr后面的区域可以容纳ShellCode,只是buf区域显然是不够的。因此,Pangr实现了分割ShellCode的存储,以解决空间碎片问题,如图3所示,ShellCode=ShellCode0+ShellCode1,清单1中针对该漏洞有两种ShellCode排列解决方案:1)当自动排列ShellCode时,Pangr可以智能地对原始ShellCode进行分段,以充分利用可控空间。同时,Pangr应该注意堆栈信息的恢复。*ptr指针必须是有效地址,但不能被无意义的填充字符替换。直接覆盖返回地址将能够实现eip控制,而ShellCode可以导致崩溃,任意地址读取,任意地址写入和shell访问;2)ShellPhish团队名为angrop的另一个工具可用于构建ROP链以绕过DEP保护。

图片.png

图3 栈漏洞利用ShellCode布局

C 堆溢出漏洞


堆溢出不直接覆盖返回地址,因此利用它非常复杂。没有研究机构或学术文章实现了自动利用堆溢出漏洞。考虑到堆利用的灵活性和复杂性,Pangr不会直接生成可以使用的exp,但根据漏洞的特征,它会自动生成一个利用方案来引导人们编写有效的exp。Pangr将堆利用方法分为9种类型,并定义了10种特征。然后Pangr根据漏洞具有的功能生成开发计划。如果漏洞满足定义的太多功能,则可能存在多种利用方案。堆漏洞利用具体方法https://heap-exploitation.dhavalkapil.com/定义的特征如表2所示。


上述9种方案都是通过伪造堆块结构来欺骗堆管理程序以在目标地址处写入给定值。然后,您可以将.got表上调用的正常函数地址更改为系统地址。使用者可以选择像atoi或free这样的常规功能,最后获得shell访问权限。

表2 堆溢出漏洞的特征

图片.png


V. 自动脆弱性修补


Pangr使用patchkit修补二进制文件。patchkit提供了一个用于修补二进制文件的python接口,因此可以直接修改二进制代码、注入代码和钩子函数。根据漏洞分析器检测到的漏洞类型,防御引擎应用不同的补丁策略,但不会影响二进制文件本身的功能。对于格式字符串漏洞,Pangr会在漏洞的地址(如printf函数)中过滤“%n”和“%s”等字符。Pangr还可以为易受攻击的函数添加“%s”参数。对于栈溢出漏洞,如果溢出是由strncpy或memcpy函数引起的,Pangr会修改其长度参数。Pangr可以用读取替换get,防止复制溢出或覆盖返回地址和其他重要数据。对于堆溢出漏洞,Pangr可以根据之前记录的块大小限制复制长度。Pangr在查找malloc函数时也可以申请更多堆空间,它可以用空指令替换自由函数以防止利用。

VI. 总结


本文提出的基于行为的漏洞检测模型,可以有效地检测和分类漏洞。其次,Pangr模型能够自动识别库函数,有效降低符号执行的复杂性。另外,Pangr在一定程度上能够实现堆溢出利用。最后,Pangr可以根据程序的漏洞类型生成防御规则(长度规则,数据规则)和相应二进制文件的补丁。


Pangr也有一些不足之处。第一,目标二进制文件是32位x86程序,因此需要扩展支持的平台。第二,Pangr采用了符号执行导致自动化漏洞利用速度慢。第三,当前的堆溢出漏洞非常复杂和多样化,Pangr对堆漏洞的利用还不够自动化。第四,漏洞建模仍然相对局限,并不能针对所有漏洞。第五,在漏洞利用方面,我们需要考虑如何绕过系统保护,如地址空间布局随机化。

如需下载原文 请点击 阅读全文 。

关于 天 方 夜 “谈”

天方夜谈原意讲不切实际的东西,而这里想要 “脚踏实地”真正弄懂并感受一篇文章的思想。

方班人有自己的浪漫,

我们探讨知识,谈论理想,

采摘科研的繁星,

脚下是星辰大海。

天:代表我们的理想犹如天空般浩荡

方:代表方班

夜:代表代码人的冷静与静谧

谈:代表方班愿与您,就领域内的经典思想和前沿成果“秉烛夜谈”