摘要:PULSAR是针对闭源的协议进行黑盒测试的基于状态机的协议模糊测试工具。其通过对专有协议的流量的观察从而推断消息格式和协议状态的模型。
一些想到的问题
-
和AFLNET的不同之处
PULSAR建立了来回消息的模板,且消息来回造成的状态转换,且其变异的模板是基于之前的消息去选择。
根据这样的特性,则pulsar对于需要登陆的协议的测试的效率更高,不会浪费时间在登录失败则会状态中循环。且其能通过状态机判断到底哪个状态是fuzzable的。
pulsar和aflnet到底谁更好?
或者说,对于需要登陆的协议,pulsar会减少浪费在登录状态循环的时间,但是其后续路径探测的广度不如AFLNET?,包括一开始的探索广度。
-
如何获取专有协议的的状态码
-
如何推断消息格式和状态机
看模型推理部分
-
如何进行测试,如何组装服务器和被测端?
对专有协议的模糊测试方法
第一步:模型推理
通过在通信网络中抓包,获取协议的网络通信样本,从而推断出马尔科夫模型,信息格式的模板和交互信息之间的数据流规则。
数据采集使用PRISMA对捕获的网络流量的消息内容和状态机进行建模。捕获一段时间所有的流量,然后对这些包进行组装,从而提供完整的信息流给会话提取器。每个流分配一个会话标识符。如果在选定的时间间隔内没有收到数据包,则会话将被标记为终止,因此同一连接中的新数据包将属于新会话。可以将间隔作为参数提供,并对其进行调优,以适应被测应用程序建立新连接的速率。如果在训练阶段没有观察到协议的部分功能,那么仅从网络跟踪中学习的模型自然会缺乏协议的部分功能。因此可以与测试应用程序生成特定的交互,以对需要审计的系统的输入和输出进行建模。
消息聚类 在收集流量记录后,将每个消息建模为字节序列。使用两种策略推断消息序列之间的共同结构,将字节序列映射到有限向量空间:
-
基于文本的协议中的消息由预定义字符分隔的字符串标记组成,每个维度都与特征向量中的单个标记相关联。所以每个维度表示消息中特定令牌的出现情况。
-
在二进制协议的情况下,使用类似于上面的方法,其中消息中的每个单独的n-gram(即特定长度的字节序列)被映射到特征向量中的相应维度。
Pulsar中对于消息聚类的目标是对于协议的不同类型的消息进行建模,所以需要聚类算法专注于消息中最有区别性的特征,文中使用别的论文PRISMA的设计,使用统计的方法去除易失性特征,从而去除每条消息中出现的常量元素。
每个消息被表示为一个向量,使用欧几里得距离作为相似性度量来应用聚类算法。从而提取通常在建模协议的某个阶段出现的公共消息结构。由于大多数协议都是由部件组装而成,将非负矩阵分解算法(NMF)应用于基于部件的聚类。将给定的数据表示为数据矩阵的因数分解(特征痕迹)。在消除重复条目之后,优化问题的解决方案使我们能够识别具有相似结构并因此属于相同类型的消息集群。该算法一般用来提取矩阵中的主成分,如下图所示
所以用于提取协议的主结构来讲是有用的。但是由于现在算力上去了,好像这玩意没有那么有意义了。
协议状态机构建 网络协议本质上是由它们的状态机定义的。由于确切的状态机只能从协议的实际实现中推断出来,PULSAR从观察到的网络轨迹中近似地获得状态机。这里与AFLNET不同:PULSAR对每条消息进行注释,指出它是由客户机还是服务器生成的。将每个消息链接到先前观察到的两个跟踪(进和出)。通过计算这些链接消息的概率,最终得到一个二阶马尔可夫模型,该模型提供了真实状态机的概率近似值。然后将马尔可夫模型最小化成有限自动机,并保留概率大于零的转换及其相关状态,并在每次转换时修改DFA以接受第二个状态的事件。
消息格式 在聚类的时候识别记录消息中出现次数比较多的token。这些token在信息流中出现的位置对应状态机中的状态转换,从而可以将token和服务的状态机对应起来。通过对相同状态下能收集到的所有token的分析,就可以改进初始的聚类阶段,从而提取出通用格式定义模板。在根据协议类型(即基于文本的或二进制的)和使用的嵌入(即令牌或字节n-gram)对每个消息进行标记后,将会话的每个消息分配给马尔可夫模型的相应状态。对于每一种状态,给具有相同数量令牌的所有消息生成一个唯一的组。如果组中的所有消息在特定位置包含相同的token,则该token将固定为常量。相反,将即使只有一次不同的标记视为变量,并且将其位置定义为字段。因此,马尔可夫模型的每个状态都与一系列模板相关联,这些模板表示在这种通信状态下可能观察到的消息的一般类型。
数据流 利用上面的会话信息,马尔可夫模型和消息模板,推断出描述会话中不同消息之间的信息流的规则。由于Pulsar关注于会话,即收和发都有,所以其可以建立报文之间的依赖关系。这样就可以利用上一条消息中的数据填充下一条中的不同字段。其考虑长度为 k = 2 的水平线上出现的每种可能的模板组合,即(t_2; t_1; t_0),然后寻找符合这个模板的所有消息,然后再会话中按照确定的消息去发送这些报文。对于这些模板中的每个字段 f,都对应到一条规则,根据规则在 f 字段中填入与之前信息不同字段的数据内容。如果没有匹配的规则,则记录这些标记,并定义一条新的数据规则,说明如何在以前看到的数据中随机选择填充 f。下图是pulsar中不同类型的规则。例如,在上图的示例中,与状态 C 相关的字段在任何情况下都可以用上一条信息的字段来填充。(规则可以理解为操作,这样读的更顺一些😀)
模板和token的具体实现方式
第二步:生成测试用例
根据前一步获取的信息,pulsar已经可以通过模板去模拟两端的通信。提取的模板和规则允许定义一组模糊原语,这些原语可以在通信的特定阶段应用于消息字段。使用这些原语,自动生成黑盒模糊测试用例。即使用之前建立的规则和模板发送模糊测试的输入。
当接收到来自通信另一端的消息时,将其匹配到存在有效转换的状态模板之一。由于协议的状态机被定义为二阶马尔可夫模型,因此有效的转换由新匹配的模板和之前匹配的两个模板以链表A:B:C的形式表示。这意味着如果观察到模板A和B,我们的系统将尝试将接收到的消息匹配到允许此转换的模板C。在需要响应的情况下,系统将使用此转换的规则集来构建下一条消息。在需要响应的情况下,系统将使用此转换的规则集来构建下一条消息。
在触发新的不同的回复时,即其token和字节都灭法匹配的时候,为了触发状态的转换,pulsar使用Levenshtein字符串距离判断接收到的消息与所有可达模板之间的相似性,然后选择最近似的。这样做有两个好处:
-
有可能达到可被模糊测试的新状态
-
如果来自相似匹配模板的语义与正确消息的语义相差太远,则响应本身可以被理解为错误的输入(即触发错误)。相当于在协议的真实状态模型中跳转到错误状态。这种情况还可能导致实现中的错误,其中网络服务无法在会话期间处理错误的消息序列或来自不同会话的消息。
在选择模板D之后,使用描述转换B:C:D的规则结合来构建下一条消息。选择包括:无效UTF-8字节序列、常量字符串溢出或随机字符串溢出(包含或不包含一定百分比的非字母数字字符)。
第三步:模型覆盖率分析
为了增加安全分析的覆盖范围,会选择适合fuzz的协议状态。为此,模糊器被引导到状态机中的子图,这些子图很少被访问,并且包含最多数量的具有可变输入字段的消息。
Fuzzing subgraph模糊子图算法选择下一个响应。算法控制fuzzer在连续迭代沿着的不同状态(即,当会话终止时由被测应用程序发起的新连接)上的进展。它的最终目的不仅是为了增加模型的探索,但更快地达到模糊状态。算法的工作流程如下:
-
模糊测试开始的时候,给每个模板分配一个掩码。掩码是一个二进制数组,其大小等于模板中的字段数,并指示下次选择此模板构建消息时将模糊哪些字段。如果模板有N个字段,则每个模板存在2^N个可能的模糊掩码。最初,每个掩码设置为2^N。
-
子图由一个根状态和能达到D转换的状态定义。子图的权重就是其状态的权值和。状态的权值是其模板在某一特定时刻掩码的和。
-
当一个消息被接收并匹配的时候,所有有效转换状态中拥有最高子图权重的状态会被选择。
-
通信继续进行直至达到一个可以模糊的状态。当一个模板被选选择时其掩码减一
修改模糊掩码会在下次选择模板时更改模板的模糊字段。此外,它还降低了其状态和前状态子图的模糊权值。因此,模型中在早期阶段有更多模糊机会的路径将首先被遍历。随着这些模板的模糊掩模的减少,子图的权重也会减少,从而允许对模型中相邻路径的探索。如果通过有效转换从当前状态到达的所有状态具有相同的子图权重,我们随机选择下一个状态。
修改掩码会改变下一次选择模板时模板的字段,还会降低其状态和之前状态子图的模糊权重。所以,模型中在早期阶段有更多模糊机会的路径将首先被选中。随着这些模板模糊掩码的减少,子图的权重也会随之减少,从而可以探索模型中的相邻路径。如果从当前状态通过有效转换可到达的所有状态都具有相同的子图权重,就随机选择下一个状态。
限制
对检测到的网络流量的完整性有依赖
没出现过的协议路径不会被建模,但是这个问题没法解决,除非白盒。或者加入再学习阶段完善。
fuzz的时候不会更改字段的类型
只更改值不更改类型,目的是减少测试值的范围,增加效率。为补救这个问题,pulsar手动为某些字段分配类型。然而,给出的结果表明,这样的方法已经能够在没有这些信息的情况下识别漏洞,从而弥补了类型信息的不足。
加密的网络流量无法处理
这个问题通常无法解决。只能使用中间人代理
本文创新点
-
自动推理协议状态机替代逆向工程
-
基于学习到的规范,对通信各方进行模糊测试,以揭示实现中的安全漏洞
另一个关键的区别是无状态和有状态协议推断。所有逆向工程网络协议方法的共同点是需要区分传输数据中的可变段和恒定段。在这方面,许多方法都基于Beddoe[4]和协议信息学项目的早期工作或受到其影响,其中使用了生物信息学领域的序列比对算法将协议消息分解为其单独的组件。