[论文分享] Large Language Model guided Protocol Fuzzing

Large Language Model guided Protocol Fuzzing [NDSS 2024]

在这里插入图片描述
如何在没有机器可读的协议规范的情况下发现协议实现中的安全缺陷? 协议实现是特别关键的安全软件系统,其中输入必须遵循特定的结构和顺序,这些结构和顺序通常在数百页的自然语言(Request For Comments,RFC)中非正式地指定。如果没有该协议的某些机器可读版本,就很难自动为遵循所需结构和顺序的实现生成有效的测试输入。在一组记录的消息序列上使用突变模糊测试作为种子输入,可以部分缓解这一挑战。然而,可用种子的集合通常是非常有限的,并且很难涵盖协议状态和输入结构的巨大多样性。
在本文中,我们探索了与预训练的大型语言模型(LLM)进行系统交互的机会,这些模型已经摄取了数百万页人类可读的协议规范,以提取有关协议的机器可读信息,这些信息可以在协议模糊测试期间使用。我们使用LLM关于知名协议的协议消息类型的知识。我们还检查了LLM通过生成消息序列和预测响应代码来检测有状态协议实现的“状态”的能力。基于这些观察,我们开发了一个L指导的协议实现模糊测试引擎。
我们的协议模糊测试器CHATAFL为协议中的每种消息类型构建语法,然后通过与LLM的交互改变消息或预测消息序列中的下一个消息。在PROFUZZBENCH的现实世界协议上的实验表明,在状态和代码覆盖方面具有显着的功效。我们的LLM制导状态模糊测试器与最先进的AFLNET和NSFUZZ模糊器进行了比较。CHATAFL分别多覆盖47.60%和42.69%的状态转换,29.55%和25.75%的状态,5.81%和6.74%的代码。除了增强的覆盖范围外,CHATAFL在广泛使用和广泛测试的协议实现中发现了9个不同的以前未知的漏洞,而AFLNET和NSFUZZ分别只发现了3个和4个漏洞。

一句话:ChatAFL:LLM指导的协议fuzzing

Introduction

从实用的角度来看,协议实现是直接或间接连接到互联网的每个软件系统中最暴露的组件。因此,协议实现构成了一个关键的攻击面,必须自动地、持续地消除安全漏洞。在广泛使用的协议实现中,一个简单的任意代码执行漏洞甚至会使最安全的软件系统容易受到恶意远程攻击。
从研究的角度来看,协议实现构成了难以测试的有状态系统。相同的输入执行两次可能每次都给出不同的输出。查找特定协议状态中的漏洞需要以正确的顺序发送正确的输入。例如,某些协议在交换其他类型的消息之前需要初始化或握手消息。为了让接收方正确解析该消息并进入下一个状态,消息必须遵循特定的格式。然而,默认情况下,我们既不知道这些消息的正确结构,也不知道它们的正确顺序。
基于突变的协议模糊通过模糊记录的消息序列[32,36,38],减少了对所需消息结构或顺序的机器可读规范的依赖。然而,基于突变的协议模糊器的有效性受到记录的种子消息序列的质量和多样性的限制,并且可用的简单突变无助于有效覆盖原本丰富的输入或状态空间。
真实情况是,为了促进互联网参与者对协议的采用,几乎所有流行的、广泛使用的协议都在公开可用的文档中进行了详细说明,这些文档通常长达数百页,用自然语言编写。如果能够以编程方式询问正在测试的协议的自然语言规范,那会怎么样? 如何利用这样一个机会来解决现有协议模糊方法的挑战?

Construction

最近LLM被证明能够准确地回答任何主题的特定问题,而这些问题来自互联网上的网站和文档,数据量高达数TB。像ChatGPT 4.0这样的LLM也使用了自然语言协议规范。最近LLM的巨大成功为我们提供了开发一个系统的机会,该系统将协议模糊器放入与LLM的系统交互中,其中模糊器可以向LLM发出非常具体的任务。

这个方法称为LLM-guided protocol fuzzing,包括是三个主要组件。

  • 首先,模糊器使用LLM为用于结构感知突变的协议提取机器可读语法。
  • 其次,模糊器使用LLM来增加作为初始种子的记录消息序列中的消息的多样性。
  • 最后,模糊器使用LLM打破覆盖率瓶颈,其中LLM被提示生成消息以到达新状态。

Contribution

  • 我们为协议实现构建了一个大型语言模型(LLM)引导的模糊测试引擎,以克服现有协议模糊测试的挑战。为了更深入地覆盖这些协议的行为,需要进行动态状态推断——这是通过询问LLM(如ChatGPT)关于给定协议的状态机和输入结构来完成的。
  • 我们提出了将LLM集成到基于突变的协议模糊器中的三种策略,每种策略都明确地解决了协议模糊的确定挑战。并实现初型机,github链接 https://github.com/ChatAFLndss/ChatAFL
  • 我们进行了实验,证明我们的LLM引导的状态模糊器原型CHATAFL在协议状态空间的覆盖范围和协议实现代码方面比最先进的AFLNET和NSFUZZ更有效。除了增强的覆盖范围外,CHATAFL还在广泛使用的协议实现中发现了9个以前未知的漏洞,其中大多数是AFLNET和NSFUZZ无法发现的。

Background

许多最广泛使用的协议都是由Internet工程任务组(IETF)设计的,并作为征求意见(RFC)发布。这些rfc大多是用自然语言编写的,可能长达数百页。例如,实时流协议(RTSP) 1.0协议作为RFC 2326发布,长达92页作为面向互联网的软件组件,协议实现对安全性至关重要。协议实现中的安全漏洞经常被用来实现远程代码执行(Remote Code Execution,RCE)。

Protocol Fuzzing

协议指定要交换的消息的一般结构和顺序。图1显示了RTSP消息结构的一个示例。

在这里插入图片描述

除了指定消息类型(PLAY)、地址和协议版本的报头外,消息由键值对(key: value)组成,由回车和换行字符(CRLF;\ r \ n)分隔开。RTSP消息所需的顺序如图2所示。从INIT状态开始,只有类型为SETUP或ANNOUNCE的消息才会导致新的状态(READY)。要从INIT状态到达PLAY状态,至少需要两个特定类型和结构的消息。

在这里插入图片描述

协议模糊器自动生成消息序列,这些消息序列在理想情况下遵循该协议所需的结构和顺序。我们可以区分两种类型的协议模糊器。
基于生成器的协议fuzzer [3,19,25]被赋予关于协议的机器可读信息,以从头生成随机消息序列。然而,协议实现本身,手工编写的生成器通常只涵盖协议规范的一小部分,其实现繁琐且容易出错[36]。
基于突变的协议fuzzer [36,38]使用一组预先录制(pre-recorded)的消息序列作为突变的种子输入。记录确保了消息结构和顺序是有效的,而突变模糊会对两者造成轻微破坏 [36]。事实上,最近提出的所有协议模糊器,如AFLNET [36]和NSFUZZ [38]都采用了这种方法。

Challenges

在这里插入图片描述

Large Language Models

LLM的功能对网络协议有各种含义。网络协议是根据RFC实现的,RFC是用自然语言编写的,可以在线使用。由于LLM是在数十亿互联网样本上进行预训练的,LLMs也应该能够理解RFC。此外,LLM已经展示了强大的文本生成能力。考虑到消息是在服务器和客户机之间传输的文本格式,为LLM生成消息应该很简单。LLM的这些功能有可能解决基于突变的协议fuzzing的公开挑战。此外,LLM固有的自动化和易于使用的属性与模糊的设计理念相协调。

Motivation

  • 为了解决初始种子(C1),我们建议要求LLM在给定的种子消息序列中添加一个随机消息。
  • 为了解决消息的未知结构(C2),我们建议要求LLM为每种消息类型提供关于消息结构(即语法)的机器可读信息。
  • 为了导航未知状态空间(C3),我们建议请求LLM,给定模糊器和协议实现之间最近的消息交换,返回将导致新状态的消息。

Case Study

研究三个问题:

  • 对于LLM生成初始种子,是否能增加信息的多样性和有效性?
  • 对于LLM提供的不同消息类型的消息结构,与基本事实相比,这些语法有多好? 它们涵盖了哪些消息类型?
  • 对于LLM导航到新的状态,是否能帮助我们过渡到一个新的状态?

在研究中,选择实时流协议(RTSP),以及它在PROFUZZBENCH [33]中的实现LIVE5552。RTSP是一个应用程序级协议,用于控制具有实时属性的数据交付。LIVE555按照RFC 2326标准实现RTSP,作为娱乐和通信系统中的流媒体服务器,对流媒体服务器进行管理。它包含在PROFUZZBENCH中,PROFUZZBENCH是一个广泛使用的网络协议状态模糊测试基准[7,36,38]。PROFUZZBENCH包括一套具有代表性的开源网络服务器,用于流行的协议,LIVE555就是其中之一。因此,LIVE555的研究结果将有力地表明LLM是否可以有效地指导协议模糊。我们的研究在的ChatGPT模型(ChatGPT-3.5)中进行。

Lifting Message Grammars: Quality and Diversity

我们要求LLM提供关于消息结构(即语法)的机器可读信息,并且我们评估生成的语法的质量和消息类型的多样性,而不是基本事实。为了建立基本正确的语法,两位作者总共花了8个小时阅读RFC 2326,并手动单独提取了完全一致的相应语法。我们最终为10种特定于RTSP协议的客户端请求提取了基本事实语法,每种请求由大约2到5个报头字段组成。

在这里插入图片描述

图3显示了PLAY消息语法,对应于图1中显示的PLAY客户端请求的语法。PLAY语法包括4个基本的报头字段:CSeq、User-Agent、Session和Range。此外,某些请求类型具有特定的报头字段。例如,Transport特定于SETUP请求,Session适用于除SETUP和OPTIONS之外的所有类型,Range特定于PLAY、PAUSE和RECORD请求。为了获得用于分析的LLM语法,我们从RTSP协议的LLM生成请求中随机抽取了50个答案,并将它们合并为一个答案集。如图4所示,LLM为所有10种消息类型生成的语法,出现在LLM的40多个回答中。此外,LLM偶尔会生成2种随机类型的客户端请求,例如“SET DESCRIPTION”;然而,每种随机类型在我们的答案集中只出现一次。

在这里插入图片描述

此外,我们还检查了LLM生成的语法的质量。对于10种消息类型中的9种,LLM生成的语法与从RFC中提取的所有答案的基本事实语法相同。唯一的例外是PLAY客户端请求,LLM忽略了一些答案中的(可选的)“Range”字段。在进一步检查整个答案集中的PLAY语法后,我们发现LLM在35个答案中准确地生成了PLAY语法,包括“Range”字段,但在15个答案中省略了它。这些发现证明了LLM生成高度准确的消息语法的能力,这促使我们利用语法来指导突变。
LLM为所有类型的RTSP客户端请求的结构生成机器可读的信息,这些信息与基本事实相匹配,尽管存在一些随机性。

Enriching the Seed Corpus: Diversity and Validity

我们要求LLM将随机消息添加到给定的种子消息序列中,并评估消息序列的多样性和有效性。在PROFUZZBENCH中,LIVE555的初始种子语料库仅包含4种类型的客户端请求,其中10种存在于ground truth中:DESCRIBE, SETUP, PLAY和TEARDOWN。由于缺少其余6种类型的客户机请求,RTSP状态机的很大一部分未被探索,如图2所示。虽然fuzzers有可能生成缺失的六种类型的客户端请求,但可能性相对较低。为了验证这一观察结果,我们检查了由最先进的fuzzers AFLNet和NSfuzz生成的种子,没有生成这些缺失的消息类型。因此,增强初始种子是至关重要的。我们可以使用LLM来生成客户端请求并扩展初始种子语料库吗?

如果LLM不仅能够生成准确的消息内容,而且能够将消息插入到客户机-请求序列的适当位置,那将是最优的。众所周知,网络协议的服务器通常是有状态的响应式系统。这个特性决定了一个客户机请求要被服务器接受,它必须满足两个必要条件:(1)它以适当的状态出现,(2)消息内容准确。

为了研究LLM的这种功能,我们要求它为10种类型的客户端请求中的每一种生成10条消息,从而产生总共100个客户端请求。随后,我们验证客户端请求是否被放置在给定客户端请求序列中的适当位置。为此,我们将它们与图2中所示的RTSP状态机进行比较,因为消息序列应该基于状态机进行传输。一旦我们确保了基于状态机的客户端请求序列是准确的,我们就将其发送到LIVE555服务器。通过检查来自服务器的响应代码,我们可以确定消息内容是否准确,从而也可以再次检查消息顺序。

在这里插入图片描述

我们的研究结果表明,LLM能够生成准确的信息并丰富初始种子。99%收集到的客户端请求被放置在准确的位置。唯一的例外是在“SETUP”客户端请求之后插入了“DESCRIBE”客户端请求。由于只有一个例外,我们认为LLM的性能是可以接受的。我们将客户机请求序列发送到LIVE555服务器,处理后的结果如表1所示。大约55%的客户端请求可以通过成功的响应代码“2xx”直接被服务器接受。然而,失败的案例并不是因为LLM的能力不足。在不成功的集合中,20.4%的消息发生是因为LIVE555不支持“ANNOUNCE”和“RECORD”的功能,尽管它包含在其RFC中。其余情况归因于“PLAY”,“TEARDOWN”,“GET PARAMETER”和“SET PARAMETER”请求中的错误会话ID。

Inducing Interesting State Transitions

我们向LLM提供模糊器和协议实现之间的消息交换,并要求它返回将导致新状态的消息。我们评估消息诱导转换到新状态的可能性。具体来说,我们为LLM提供了现有的通信历史记录,使服务器能够分别到达每个状态(即INIT, READY, PLAY和RECORD)。之后,我们查询LLM以确定可能影响服务器状态的下一个客户机请求。为了减轻LLM随机行为的影响,我们在每个状态下对LLM进行了100次提示。

在这里插入图片描述

图5显示了结果。每个饼状图展示了每个states的结果。每个饼图中的每个段表示不同类型的客户端请求。灰色部分表示可能导致状态更改的客户端请求类型的百分比。橙色的表示出现在适当状态的消息类型,但不触发任何状态转换(因此没有状态更改)。蓝色表示出现在不适当状态下的类型,这些类型将被服务器直接拒绝。
从图5中,我们可以看到分别有81%、74%、89%和69%的客户端请求可以诱导状态转换到不同的状态。此外,大约17%、16%、10%和30%的客户端请求仍然可以被服务器接受和处理,尽管它们不会触发状态更改。
这些消息对于覆盖更多的代码分支仍然有潜在的用处,尽管它们无法覆盖更多的状态。此外,还有一小部分不恰当的信息,在我们的案例研究中分别占2%、10%、1%和1%左右。这些结果表明LLM具有推断协议状态的能力,尽管偶尔会出现错误。

在LLM生成的客户端请求中,69%到89%诱导转换到不同的状态,覆盖了每个单独状态的所有状态转换。

Design

在案例研究中LLM展示的令人印象深刻的能力的激励下,我们开发了LLM引导的协议模糊测试(LLMPF)来解决现有的基于突变的协议模糊测试(EMPF)的挑战。
算法1 (不包括灰色部分)指定了经典EMPF方法的一般过程。输入是正在测试的协议服务器 P 0 P_0 P0、对应的协议 p p p、初始种子语料库 C C C和总fuzz时间 t t t。输出由最终种子语料库 C C C和使服务器崩溃的种子 C × C_{×} C×组成。在每次模糊迭代中(第7-34行),EMPF选择一个渐进状态 s s s(第7行)和序列 M M M(第8行),该序列 M M M练习 s s s来引导模糊器探索更大的空间。为保证所选状态 s s s得到执行,将 M M M分成三部分(第9行): M 1 M_1 M1,达到 s s s的序列; M 2 M_2 M2,选择突变的部分; M 3 M_3 M3为剩余子序列。随后,EMPF为 M M M分配能量(energy)(第10行)以确定突变时间,然后将其突变为具有新突变子的 M ′ M ' M(第16行)。然后将这个突变序列发送到服务器(第23行)。EMPF保存导致崩溃的或增加代码或状态覆盖的 M ′ M ' M(第24-25行)(第27-28行)。如果是后者,则更新状态机(第29行)。这个过程重复进行,直到分配的能量耗尽(第10行),此时选择下一个状态。

在这里插入图片描述

对于我们的LLMPF方法,我们通过合并灰色组件来增强EMPF的基线逻辑:(1) 通过提示LLM提取语法(第2行),并利用语法引导模糊突变(第12-14行); (2) 查询LLM以充实初始种子(第3行); (3) 利用LLM的能力突破覆盖瓶颈(第4、19-21、26、30和32行)。现在我们将介绍每个组件。

Grammar-guided Mutation

在本节中,我们将介绍从LLM中提取语法的方法,然后利用语法来指导结构感知的突变。
(1) Grammar Extraction:在模糊器可以要求LLM生成用于结构感知突变的语法之前 [37],我们遇到了一个直接的挑战:如何为模糊器获得机器可读的语法?
不幸的是,LLM生成的响应通常是具有相当灵活性的自然语言结构。如果模糊器要理解LLM的反应,LLM应该始终以预定的格式回答我们的模糊器提出的问题。另一种选择是手动将LLM的响应转换为所需的格式。然而,这种方法会损害模糊器的高度自动化特性,这是不太可取的。因此,当前的问题是如何使LLM以所需的格式回答问题。
为了使LLM生成机器可读的语法,我们最终在提示工程领域使用了上下文内的少量学习。上下文学习是对模型进行微调的有效方法。通过一些期望输入和输出的例子,利用few-shot学习来增强上下文。这使LLM能够识别输入提示符语法和输出模式。使用上下文中的少量学习,我们用几个示例提示LLM以所需格式提取协议语法。
图6演示了用于提取RTSP语法的模型提示符。在这个提示中,fuzzer以所需的格式提供了来自两个不同协议的两个语法示例。在这种格式中,我们保留语法中的消息关键字,我们认为它是不可变的,并用⟨Value⟩替换可变区域。请注意,为了指导LLM正确生成语法,我们使用了两个示例,而不是依赖于单个示例。这有助于防止LLM严格遵守给定的语法,并可能忽略重要的事实。

在这里插入图片描述

此外,在我们的案例研究中还发现了另一个问题:LLM可能偶尔会产生随机答案,比如“SET DESCRIPTION”。幸运的是,这种情况很少发生。为了解决少数样本生成的随机性,我们与LLM进行了多次对话,并将大多数一致的答案视为最终语法。这种方法与提示工程领域的自一致性检查 [45]有相似之处,但它不会发生在思维链提示中。
通过这些方法,模糊器能够有效地从各种协议的LLM中获得准确的语法。图6中显示的模型输出演示了从LLM派生的RTSP语法的一部分。在实践中,LLM有时对这个提示中的“all”不敏感,导致它们只生成部分语法类型。为了解决这个问题,我们只需再次提示LLM询问剩余的语法。
在开始模糊测试活动之前(请参阅概述中算法1的第2行),我们的LLMPF方法与LLM进行对话以获取语法。随后,该语法被保存到语法语料库G中,在整个活动中使用该语料库进行结构感知突变。这种设计旨在最小化与LLM交互的开销,同时确保最佳的模糊测试性能。接下来,我们详细阐述基于提取的语法为结构感知模糊提供指导的方法。

(2) Mutation based on Grammar:利用从LLM中提取的语法语料库,LLMPF对种子消息序列进行结构感知的突变。在之前的工作[23]中,研究人员利用LLM理解输入语法的能力,生成给定输入的变体。然而,会话开销限制了与LLM交互的频率。在我们的方法中,我们采用了不同的策略。LLMPF利用提取的语法来指导突变。模糊器只提取一次语法,使其能够在整个模糊测试活动中合并语法。
在算法1的第9行中,模糊器选择消息部分M2进行突变,作为算法设计的一部分。假设M2由多个客户端请求组成,其中一个是RTSP协议的PLAY客户端请求。我们在语法指导下的突变方法如图7所示。它展示了改变一个RTSP PLAY客户端请求的工作流程。具体来说,当出现PLAY客户端请求时,LLMPF首先将其与相应的语法进行匹配。为了加快匹配过程,我们按照映射格式维护语法语料库:G = {type→grammar}。这里,type表示客户端请求的类型。LLMPF使用每个语法的第一行作为消息类型的标签。语法对应于具体的消息语法。LLMPF使用消息类型检索相应的语法。随后,我们使用正则表达式(Regex)将消息中的每个报头字段与语法匹配,将区域标记为’⟨Value⟩'下的可变区域。

在这里插入图片描述

在图7中,这些标识的可变区域以蓝色突出显示。在突变期间,LLMPF只选择这些区域,确保消息保留有效格式。但是,如果没有找到语法匹配,我们认为所有区域都是可变的。

Enriching Initial Seeds

受LLM生成新消息并将其插入所提供消息序列中的适当位置的能力的激励,我们建议丰富用于模糊的初始种子语料库(算法1的第3行)。然而,我们的方法必须首先解决几个挑战: (i) 如何生成携带正确上下文信息的新消息(例如,RTSP协议中的正确会话ID)?(ii) 如何使生成序列的多样性最大化? (iii) 如何提示LLM从给定的种子消息序列生成整个修改后的消息序列?

对于挑战(i),我们发现LLM可以从提供的消息序列中自动学习所需的上下文信息。例如,对于我们的实验,PROFUZZBENCH已经拥有一些消息序列作为初始种子(尽管它们缺乏多样性)。PROFUZZBENCH的初始种子是通过捕获被测试服务器和客户端之间的网络流量来构建的。因此,这些初始种子包含来自服务器的正确和充分的上下文信息。因此,当提示LLM时,我们包含来自PROFUZZBENCH的初始种子,以方便获取必要的上下文信息。

对于挑战(ii), fuzzer确定初始种子中缺少哪些类型的客户端请求,即LLM应该生成哪些类型的消息来丰富初始种子。在上节中,获得了所有类型的客户端请求的语法; 因此,确定初始种子中缺失的类型并不是一个困难的问题。让我们回顾一下图6所示的语法提示。提示符包括消息类型的名称(例如,PLAY和GET),相应地,消息名称也包含在模型输出中(例如,DESCRIBE和SETUP)。我们利用这些信息来维护一组消息类型:AllTypes = {messageType},以及一个从语法到相应类型的映射:G2T = {grammar→type}。
在检测缺失的消息类型时,我们首先利用上节中获得的语法语料库G和语法到类型映射G2T来获取现有的消息类型,并将其维护为一个集合(即ExistingTypes)。因此,缺失的消息类型在补充中:MissingTypes = (AllTypes - ExistingTypes)。然后,我们指示LLM生成缺失类型的消息并将其插入初始种子;因此,我们的方法是基于现有的初始种子,但丰富了它们。

在这里插入图片描述

对于挑战(iii),为了保证生成的消息序列的有效性,我们将提示设计为延续格式(即“修改后的客户端请求序列为:”)。在实践中,除了删除开头的换行符(\n)或在末尾添加任何缺失的分隔符(\r\n)之外,获得的响应可以直接用作种子。图8给出了一个说明性示例。在这种情况下,我们指示LLM在给定的序列中插入两种类型的消息,“SET PARAMETER”和“TEARDOWN”。修改后的序列如图所示。

Surpassing Coverage Plateau

探索看不见的状态对状态模糊器提出了挑战。为了更好地理解这个挑战,让我们回顾一下图2所示的RTSP状态机。假设服务器在接受一系列客户端请求后当前处于 R E A D Y READY READY状态。如果服务器打算转换到不同的状态(例如, P L A Y PLAY PLAY R E C O R D RECORD RECORD状态),客户端必须发送相应的 P L A Y PLAY PLAY R E C O R D RECORD RECORD请求。在模糊设计的上下文中,模糊器承担客户端的角色。虽然模糊器具有生成诱导状态转换的消息的能力,但它需要探索相当数量的种子。fuzzer很可能无法生成合适的消息顺序来覆盖所需的状态转换[7,36]。因此,代码空间的很大一部分仍未被开发。因此,为了彻底测试有状态服务器,探索其他状态是很重要的。不幸的是,对于现有的状态模糊器来说,完成这项任务具有挑战性。
在本文中,当模糊器变得无法探索新的覆盖范围时,我们将这种情况称为模糊器进入覆盖瓶颈。受第 Inducing Interesting State Transitions 节研究结果的启发,我们利用LLM来协助模糊器超越覆盖瓶颈。当模糊器无法在给定的时间段内产生有趣的种子时,就会出现这种情况。我们根据模糊器不断产生的无趣种子的数量来量化这个持续时间。具体来说,在整个模糊测试过程中,我们维护一个名为PlateauLen的全局变量,以跟踪到目前为止连续观察到的无趣种子的数量。在开始模糊活动之前,将PlateauLen初始化为0(算法1的第4行)。在每次模糊迭代期间,如果遇到导致程序崩溃的种子(第26行)或覆盖率增加(第30行),PlateauLen将重置为0。否则,如果认为种子不有趣,则PlateauLen加1(第32行)。

在这里插入图片描述

根据PlateauLen的值,判断模糊器是否进入覆盖瓶颈。如果PlateauLen不超过MaxPlateau,即预定义的覆盖瓶颈的最大长度(第11行),我们的LLMPF将使用前面介绍的策略改变消息。MaxPlateau的值由用户指定并提供给fuzzer。然而,当PlateauLen超过MaxPlateau时,我们认为fuzzer已进入覆盖瓶颈。在这种情况下,LLMPF将利用LLM来克服覆盖瓶颈(第19-21行)。为了实现这一点,我们使用LLM来生成下一个合适的客户端请求,这些请求可能会导致状态转换到其他状态。提示模板如图9所示。
我们为LLM提供服务器和客户端之间的通信历史记录;也就是说,客户端请求和相应的服务器响应。为了确保LLM生成真实的消息,而不是消息类型或描述,我们通过从初始种子语料库中提取任何消息来演示所需的格式。随后,LLM推断当前状态并生成下一个客户机请求 M 2 ′ M_2' M2。此请求充当原始 M 2 M_2 M2的变体,并插入消息序列 M ′ M' M,然后将其发送到服务器。
让我们重新考虑 R T S P RTSP RTSP的例子。最初,服务器处于 I N I T INIT INIT状态。当接收到消息序列 M 1 = S E T U P M_1 = {SETUP} M1=SETUP时,它响应 R 1 = 200 − O K R_1 = {200-OK} R1=200OK,转换到 R E A D Y READY READY状态。随后,模糊器会遇到一个覆盖瓶颈,在那里它无法产生有趣的种子。注意到这一点后,我们通过呈现通信历史 H = S E T U P , 200 − O K H = {SETUP, 200-OK} H=SETUP,200OK来刺激LLM。作为回应,LLM极有可能回复 P L A Y PLAY PLAY R E C O R D RECORD RECORD消息,如第 Inducing Interesting State Transitions 部分的研究结果所示。这些消息将导致服务器转换到不同的状态,从而克服覆盖瓶颈期。

Evaluation

Implementation

我们将这种LLM引导的协议模糊测试(参见算法1)实现到AFLNET [36]中,称为CHATAFL,以测试用C/C++编写的协议。
它维护一个推断状态机,并使用状态和代码反馈来指导模糊测试活动。当前状态的识别涉及解析来自服务器响应消息的响应代码。如果种子增加了状态或代码覆盖率,那么它就被认为是有趣的。CHATAFL继续利用这种方法,同时无缝地将上述三种策略集成到AFLNET框架中。

在这里插入图片描述

(1) Configuration Parameters
为了确定饱和度,我们将覆盖瓶颈的最大长度(MaxPlateau)设置为512个不增加覆盖的消息序列。该值是通过启发式筛选方法确定的。在初步实验中,我们发现512是MaxPlateau的合理设置,大约在10分钟内实现。设置太小会导致CHATAFL过度查询LLM,而设置太大会导致CHATAFL停留太长时间,而不是从我们的优化中受益。一旦达到覆盖瓶颈,CHATAFL提示LLM生成超过覆盖瓶颈的消息序列。为了限制LLM提示的成本,我们将MaxPlateau的四分之一设置为无效提示的最大数量。

(2) Benchmark and Baselines
表II 列出了我们评估中使用的项目程序。我们的基准测试包含6个基于文本的网络协议实现,包括5个广泛使用的网络协议(即RTSP、FTP、SIP、SMTP和DAAP)。这些课题涵盖了PROFUZZBENCH中所有基于文本的网络协议,PROFUZZBENCH是一个广泛使用的评估有状态协议模糊器的基准[32,36,38]。这些协议涵盖了广泛的应用,包括流媒体、消息传递和文件传输。这些实现是成熟的,在企业和个人用户中都得到了广泛的应用。对于每个协议,我们选择了流行且适合在实际应用程序中使用的实现。这些项目中的安全漏洞可能会产生影响广泛的后果。

在这里插入图片描述

作为基线工具,我们选择了AFLNET和NSFUZZ-v。由于我们的工具CHATAFL已经实现到AFLNET中,因此CHATAFL和AFLNET之间观察到的每一个差异都可以归因于我们为实现LLM指导而进行的更改。AFLNET [36]是一个流行的开源、最先进、基于突变、代码和状态引导的协议模糊器。NSFUZZ-v [38]扩展了AFLNET,以更好地处理协议状态空间。

(3) Variables and Measures
为了评估CHATAFL与基线模糊器的有效性,我们测量了协议模糊器覆盖协议状态空间和协议实现代码的程度。关键思想是协议模糊器不能在未覆盖的代码或状态中找到错误。然而,覆盖率只是fuzzer发现bug能力的一个代理度量。因此,我们用bug查找结果来补充覆盖率结果。
Coverage. 我们报告代码和状态空间的覆盖率。为了评估代码覆盖率,我们使用基准测试平台PROFUZZBENCH [33]提供的自动化工具来测量分支覆盖率。为了评估状态空间的覆盖率,我们使用基准测试平台提供的自动工具测量不同状态的数量(状态覆盖率)和这些状态之间的转换数量(转换覆盖率)。
Bugs. 为了识别错误,我们在地址消毒器(ASAN)下执行测试过的程序。CHATAFL存储崩溃消息序列,然后我们使用AFLNET提供的AFLNetreplay实用程序来重现崩溃并调试潜在原因。我们通过分析ASAN报告的堆栈跟踪来区分不同的bug。最后,我们将这些错误报告给相应的开发人员进行确认。

(4) Experimental Infrastructure
所有实验都是在一台配备Intel Xeon Platinum 8468V CPU的机器上进行的。这台机器有192个逻辑内核,运行频率为2.70GHz。它运行在Ubuntu 20.04.2 LTS上,主内存为512GB。

State Space Coverage

Transitions. 表III显示了我们的工具CHATAFL与两个基线AFLNET和NSFUZZ-v所覆盖的状态转换的平均数量。为了量化CHATAFL在基线上的改进,我们报告了在24小时内实现的转换覆盖的百分比改进(Improv), CHATAFL在24小时内实现与基线相同的转换覆盖的速度有多快(Speedup),以及CHATAFL的随机活动优于基线的随机活动的概率。
与这两个基线相比,CHATAFL执行了更多的状态转换,并显著加快了状态探索过程。平均而言,CHATAFL比AFLNET多执行48%的状态转换。具体来说,在LIVE555主题中,与AFLNET相比,CHATAFL将状态转换的数量增加了91%。此外,CHATAFL探索相同数量的状态转换的速度平均比AFLNET快48倍。与NSFUZZ相比,CHATAFL平均多覆盖43%的状态转换,并以16倍的速度实现相同数量的状态转换。

在这里插入图片描述

States. 表IV显示了我们的工具CHATAFL与两个基线AFLNET和NSFUZZ-v所覆盖的平均状态数以及相应的改进百分比。显然,CHATAFL的性能优于AFLNET和NSFUZZ。具体来说,CHATAFL覆盖的states比AFLNET多30%,比NSFUZZ多26%。为了将覆盖的状态数量放在可达状态总数的上下文中,表4的最后一列显示了在24小时的10次运行中,这三个工具中的任何一个已经覆盖的状态总数。我们可以看到,CHATAFL的平均模糊运动几乎涵盖了所有可达状态。例如,在LIVE555的例子中,CHATAFL平均覆盖了15个states中的14.2个states,而AFLNET和NSFUZZ分别只覆盖了10个states和11.7个states。只有在Kamailio中,CHATAFL覆盖的可达状态空间比例较小(平均17个;最多23个states中的20个)。尽管如此,CHATAFL在各states覆盖率方面仍然优于基线。

在这里插入图片描述

Code Coverage

表5显示了CHATAFL和基线AFLNET和NSFUZZ在10个24小时的模糊测试活动中实现的平均分支覆盖率。为了量化CHATAFL在基线上的改进,我们报告了24小时内分支覆盖率的百分比改进(Improv), CHATAFL在24小时内实现与基线相同分支覆盖率的速度(speedup),以及CHATAFL随机活动优于基线随机活动的概率( A ^ 12 \hat{A}_{12} A^12)。

在这里插入图片描述
正如我们所看到的,对于所有项目,CHATAFL覆盖的分支比两个基线都多。具体来说,CHATAFL比AFLNET多覆盖5.8%的分支机构,覆盖范围从2.4%到8.0%不等。与NSFUZZ相比,CHATAFL覆盖的分支多6.7%。此外,CHATAFL覆盖相同分支数量的速度比AFLNET快6倍,比NSFUZZ快10倍。对于所有受试者,varga-delaney 效应大小 ≥ 0.70表明,在代码覆盖率方面,CHATAFL在两个基线上都具有实质性优势。

Ablation Studies

在这里插入图片描述

为了评估每种策略对增加覆盖率的贡献,我们进行了消融研究。为此,我们开发了四个工具:

  • CL0: AFLNET, i.e., all strategies all are disabled,
  • CL1: AFLNET plus grammar-guided mutation (SA),
  • CL2: AFLNET plus grammar-guided mutation (SA) and enriching initial seeds (SB)
  • CL3: AFLNET plus all strategies (SA + SB + SC), i.e.,CL3 is CHATAFL.

表VI显示了我们之前使用的类似格式(Improv、Speedup和 A ^ 12 \hat{A}_{12} A^12)中分支覆盖率的结果。然而,与之前的表格相比,关键的是,在改进,加速和 A ^ 12 \hat{A}_{12} A^12效应大小方面的结果呈相反方向。例如,对于ProFTPD,配置CL3(即CHATAFL)比基线配置CL0(即AFLNET)实现了8%以上的分支覆盖率。两个相邻配置之间的改进差异(括号中所示)量化了启用策略的效果。例如,对于ProFTPD,配置CL2仅实现了5.3%的改进,比CL3低2.7个百分点(pp),这表明从CL2到CL3启用的SC策略的有效性。

在这里插入图片描述

所有策略都有助于提高分支机构覆盖率,并且没有策略对分支机构覆盖率产生负面影响。具体而言,与CL0相比,CL1导致分支覆盖率平均增加3.04%。CL2平均增长3.9%,CL3平均增长5.9%,增幅最大。此外,CL1实现相同分支覆盖的速度比CL0快2倍,CL2实现相同分支覆盖的速度比CL0快5倍,CL3实现相同分支覆盖的速度比CL0快6倍。因此,实施所有三种战略被证明是最有效的办法。

Strategy S A S_A SA. 我们评估了SA策略(即基于语法的突变)的影响。在ProFTPD、PureFTPD、Exim和forked-daapd中,CL1将分支覆盖率提高了2.4%到6.7%。而在其余两个被试Live555和Kamailio中,CL1虽然也提高了分支覆盖率,但分别只提高了0.28%和0.60%。在研究这两个主题的实现后,我们发现它们的实现并不严格遵守消息语法。报头字段缺失或错误的消息仍然可以被服务器接受。
Strategy S B S_B SB. 与仅启用策略SA的CL1相比,我们观察到策略SB的贡献。平均而言,启用策略导致分支覆盖增加0.82%。策略SB显著提高了Live555、ProFTPD和Kamilio的分支覆盖率1.21% ~ 1.64%,而在其他3个受试者中分支覆盖率仅提高了0.03% ~ 0.26%左右。对于后三个主题,PROFUZZBENCH包括几乎所有类型的客户请求; 因此,增加种子多样性的机会不大。
Strategy S C S_C SC. 当比较CL3和CL2时,我们可以观察到启用策略 S C S_C SC显著增加了分支覆盖率,从0.69%增加到4.78%。特别是在ProFTPD和Kamailio中,策略 S C S_C SC分别帮助增加了2.72%和4.78%的分支覆盖率。

Discovering New Bugs

在这个实验中,我们通过检查CHATAFL是否能够在我们的主题程序中发现零日漏洞来评估它的效用。为此,我们在最新版本的受试者上使用CHATAFL,在24小时内重复10次。在实验过程中,CHATAFL产生了令人满意的结果,如表7所示。

在这里插入图片描述
尽管AFLNET和NSFUZZ进行了广泛的测试,CHATAFL还是发现了9个独特的、以前未知的漏洞。在六个测试实现中的三个中发现了漏洞,并且包含各种类型的内存漏洞,包括use-after-free、缓冲区溢出和内存泄漏。此外,这些错误具有潜在的安全隐患,可能导致远程代码执行或内存泄漏。我们向各自的开发人员报告了这些错误。在这9个bug中,有7个已经被开发者确认,3个已经被修复(到论文提交时间)。我们已经为确认的bug请求了CVE ID。

为了理解LLM的贡献,我们对Bug #1进行了更详细的调查,这是一个heap-use-after-free漏洞。当在处理PAUSE客户端请求期间,为特定轨道的使用环境分配的内存被重新分配时,就会出现此错误。随后,该内存在收到PLAY客户端请求时被覆盖,导致free后的堆使用问题。为了触发此错误,必须涉及几种类型的客户端请求:SETUP、PLAY和PAUSE。但是,在以前的工作中使用的初始种子中没有包含PAUSE客户机请求。虽然理论上fuzzers可以生成这样的客户端请求,但这是不可能的。我们在实验中检查了由AFLNET和NSFUZZ生成的所有种子,发现它们在任何运行中都没有产生PAUSE客户机请求。但是,CHATAFL会提示LLM在初始种子的丰富过程中添加PAUSE客户端请求。

Summary

CHATAFL设计用于使用公开可用的rfc测试基于文本的协议。大多数协议的规范都记录在这些公开可用的RFC中,这些RFC作为LLM的训练数据包括在内。然而,对于某些专有协议,其RFC未包含在LLM训练数据中,CHATAFL在测试它们时可能无法实现最佳性能。

References

[3] D. Aitel, “The advantages of block-based protocol analysis for security testing,” Immunity Inc., February, vol. 105, p. 106, 2002.
[7] J. Ba, M. B ̈ ohme, Z. Mirzamomen, and A. Roychoudhury, “Stateful greybox fuzzing,” in Proceedings of the 31st USENIX Security Symposium. USENIX Association, 2022, pp. 3255–3272.
[19] M. Eddington, “Peach fuzzer platform.” [Online]. Available: https: //gitlab.com/gitlab-org/security-products/protocol-fuzzer-ce
[25] Jtpereyda, “Boofuzz: A fork and successor of the sulley fuzzing framework.” [Online]. Available: https://github.com/jtpereyda/boofuzz
[32] R. Natella, “Stateafl: Greybox fuzzing for stateful network servers,” Empirical Software Engineering, vol. 27, no. 7, p. 191, 2022.
[33] R. Natella and V.-T. Pham, “Profuzzbench: A benchmark for stateful protocol fuzzing,” in Proceedings of the 30th ACM SIGSOFT international symposium on software testing and analysis. ACM, 2021, pp. 662–665.
[36] V. Pham, M. B ̈ ohme, and A. Roychoudhury, “Aflnet: A greybox fuzzer for network protocols,” in Proceedings of the 13th IEEE International Conference on Software Testing, Verification and Validation: Testing Tools Track. New York: IEEE, 2020.
[37] V.-T. Pham, M. B ̈ ohme, A. E. Santosa, A. R. C ̆ aciulescu, and A. Roychoudhury, “Smart greybox fuzzing,” IEEE Transactions on Software Engineering, vol. 47, no. 9, pp. 1980–1997, 2021.
[38] S. Qin, F. Hu, Z. Ma, B. Zhao, T. Yin, and C. Zhang, “Nsfuzz: Towards efficient and state-aware network service fuzzing,” ACM Transactions on Software Engineering and Methodology, 2023.
[45] X. Wang, J. Wei, D. Schuurmans, Q. Le, E. Chi, S. Narang, A. Chowdhery, and D. Zhou, “Self-consistency improves chain of thought reasoning in language models,” in Proceedings of the 11th International Conference on Learning Representations, 2023.

Insights

(1) 再做成体系的实验前,可以用case study验证想法有效性、可行性。
(2) LLM可以对见过文档的协议,生成符合语法的请求。但是对未见文档的协议是否能帮助人恢复协议请求的数据结构?
(3) 突破覆盖率瓶颈的方法,本质上是利用LLM生成协议状态转换的下一个客户端请求,是否可以用到非LLM的方法上?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值