行业知识
阅读笔记——《基于测试用例自动化生成的协议模糊测试方法》
2026-10-23 14:57:43
来源:互联网转载
- 【参考文献】徐威,武泽慧,王子木等.基于测试用例自动化生成的协议模糊测试方法[J].计算机科学,2023,50(12):58-65.
- 【���】本文仅为作者个人学习笔记,如有冒犯,请联系作者删除。
目录
摘要
一、引言
二、相关背景
1、协议分类
2、协议模糊测试
三、测试用例及状态迁移路径生成
1、系统设计
2、协议格式以及状态机模型推断
3、基于模板的测试用例自动生成
4、状态迁移路径生成
5、网络异常监测
四、实验
1、实验设置
2、格式准确性评估
3、生成测试用例的数量以及准确性
4、漏洞发现能力评估
五、总结
摘要
- 网络协议作为设备之间交互的规范,在计算机网络中发挥着至关重要的作用。协议实体中的漏洞会使设备遭受远程攻击,存在巨大的安全隐患。模糊测试是发现程序中安全漏洞的重要方法。在对协议进行模糊测试之前需要对其进行逆向分析,在协议格式以及状态机模型的指导下生成高质量的测试用例。
- 本文提出了一种自动化的测试用例生成技术。在模板中定义测试用例生成规则,基于状态迁移路径生成算法构建完备的测试路径,有效地对协议程序进行模糊测试。
- 实验结果表明,与当前先进的协议模糊器Boofuzz相比,所提方法的有效测试用例生成数量增加了51.8%。
一、引言
- 模糊测试根据测试用例的生成方式可以分为基于突变的模糊测试技术和基于生成的模糊测试技术。
- 基于突变的模糊测试技术不需要掌握协议的先验知识,减少了创建状态机需要的时间。然而,该方式生成的测试用例往往无法通过协议格式校验。
- 基于生成的模糊测试技术,该方法通过对协议的分析获取协议的格式以及状态机模型,生成尽可能符合协议规范的测试用例。其生成的测试用例更容易被协议实体程序所接受,但是需要进行大量的人工分析以及对协议有足够的了解,且难以根据新的协议特性进行扩展。
- 另一方面,现有的基于生成的模糊测试工具如 Peach 和 Boofuzz 不关心协议程序执行时的信息,很难探测到协议的深层次状态空间。 由于基于突变的协议模糊测试工具不了解协议的状态转换关系,因此同样难以到达深层次的状态。此外,基于突变的协议模糊测试工具往往会选择更短的状态迁移路径,从而忽略了达到该状态的其他路径,造成测试不够完备的问题。
- 为了解决上述问题,本文的贡献如下:
- 提出了一种测试用例自动化生成方法,通过基于关键字的协议逆向技术来推断出协议格式以及状态机模型。根据推断出的协议格式构建模板,依据模板自动化地生成测试用例。
- 提出了一种协议状态深层次覆盖方法,根据构建的状态机生成测试路径,实现深层次的协议状态覆盖以及执行到达该状态的所有路径。
- 构建了自动化测试用例生成的模糊测试工具NAPfuzz。
- 实验结果表明,NAPfuzz在没有协议先验知识的情况下,能够基于网络流量准确推断出协议的格式以及状态模型,通过构建模板自动生成符合协议规范的测试用例。
二、相关背景
1、协议分类
- 根据请求和响应数据是否独立,网络协议可以分为有状态协议和无状态协议。
- 无状态协议,如 HTTP、UDP,客户端逐个发送的请求数据之间没有依赖关系,服务器只响应接收到的客户端数据,而不依赖于之前的请求和响应数据。测试无状态的协议时,通过构建符合格式的测试用例,可以覆盖到较多的代码空间,测试难度较低。
- 有状态协议的输出不仅与输入有关,还与协议程序当前的状态有关。大多数应用层协议都是有状态的,如 RTSP、FTP协议。测试有状态协议时,不仅需要考虑协议的格式,还需考虑协议的状态转换关系。
- 通常使用如图1所示的协议状态机模型,描述一个协议的输入输出以及状态之间的对应关系。
2、协议模糊测试
- 协议模糊测试工作流程如图2所示,主要包括预处理、变异策略选择、测试用例生成、模糊测试执行、异常判断和结果分析。
- 根据测试用例生成方式的不同,可以将模糊测试分为基于生成和基于突变两类。
- 基于突变的协议模糊测试技术使用特定的策略以及算法对符合格式的输入(通常是捕获的pcap包)进行变异,生成新的测试用例。
- 基于生成的协议模糊测试技术根据获取的协议规范,生成能够通过协议格式校验的测试用例,对协议实体程序的代码空间进行测试。
- 在预处理阶段,基于生成的模糊测试技术需要获取协议规范,用于指导测试用例的生成。代表性的工作有 Peach、Boofuzz以及SNOOZZ。这类模糊器在测试前需要研究人员掌握协议的先验知识,手动编写脚本定义的报文格式以及状态模型。
- 在异常判断的过程中,如果测试程序崩溃或无法收到测试程序的响应,协议模糊器就会将这些异常信息以及造成此次异常的测试用例保存下来,通过人工分析判断是否为一个真正的漏洞。
三、测试用例及状态迁移路径生成
1、系统设计
- NAPfuzz的目标是在没有协议先验知识的情况下,通过协议格式逆向技术构建模板,自动化生成符合协议规范的测试用例。依据协议状态机,生成覆盖所有协议状态的测试路径。最后基于网络流量探测,判断测试程序的异常状态。NAPfuzz的模糊测试流程如图3所示。
- 首先通过协议嗅探工具如Wireshark、Tcpdump等,捕获协议实体程序通信时的网络流量。在捕获到足够的流量后,由于这些数据通常由多种协议通信产生,因此需要根据IP地址以及端口号等信息对其进行过滤。
- 然后,使用优化的多序列比对算法对齐报文序列,通过确定协议的关键词进行聚类分析,进而推断出协议的格式以及状态机模型。
- 接着根据推断出的协议格式构建模板,定义报文的可变字段,以及字段之间的关系等语义信息。
- 最后,依据模板自动化生成丰富的测试用例,并根据推断出的协议状态机模型,指导测试路径的生成以及消息序列的发送。
2、协议格式以及状态机模型推断
- 本文采用基于网络流量的协议逆向技术,根据Wireshark捕获到的网络流量,推断出协议格式以及状态机模型,用于指导测试用例及测试路径的生成,实现深层次状态及其迁移路径的覆盖。
- 此步骤主要沿用了当前最先进的开源协议逆向工具Netzob的方法,并在其基础上进行了改进,以提高协议格式推断的准确性。
- Netzob利用基于语义的Needle-man-Wunsch (NW)算法对齐报文序列并计算相似性分数,之后根据这些分数进行聚类,通过分析集群内报文的共性得到协议格式。
- 然而,Netzob在语义收集阶段需要测试人员进行手工操作且对待测协议有一定了解。此外,由于报文内容的多样性大大降低了对齐的质量,因此造成了错误的聚类结果。
- 在实际的通信过程中,客户端或者服务端在接收到消息时,通过关键字确定报文的类型。本节将进一步完善Netzob的格式推断方法,在识别关键词的基础上提高聚类结果的准确性,进而得到更准确的协议格式以及状态机模型。
- 本文将关键字作为报文聚类的依据。关键字通常在报文序列中的动态字段中产生,简单的协议报文格式具有相同的结构,关键字所在的偏移位置也相同。而复杂协议中,报文具有不同的长度,关键字所在的偏移位置会有偏差,如图4所示。
- 因此,本文首先使用改进的多序列对比算法将所有的报文序列通过插入“-”符号对齐。具体算法如算法1所示。
- 在对齐过程中,如果报文当前偏移位置字段为空,将使用“-”符号进行填充。
- 依据对齐后的结果可以将其划分为不同的字段,并且将连续相等的多个静态字段合并成为一个长静态字段。使用上述算法将图4中的报文序列对齐后得到图5所示的结果。
- 关键字一定是在动态字段中产生,因此将图5中的f1、f3、f4、f5、f8作为候选的关键字。(f0、f2、f9的内容相同,为静态字段;f6、f7的内容都不相同,不会为关键字)对于f10字段,mc0、mc1等报文序列对应的值为空,不可能是关键字,同样可以将其忽略。
- 之后将对候选关键字进行度量,进一步确定这些字段作为关键字的概率,概率最大的字段将被确定为协议的关键字段。度量主要基于以下几个方面:
- 基于关键字聚类后,同一集群中报文序列应当具有高度的相似性。
- 同一集群内的报文之间应当具有相同的结构。
- 关键字在所有的报文序列中同时出现,且长度固定。
- 报文相似度评分
- 本文引入编辑距离,来确定报文间的相似度。两个报文 和 之间的相似性得分 的计算式如式(1)所示:
- 其中, 表示 和 转变成两个相同的序列时需要的最少的增加、删除或者替换操作次数。
- 表示 和 中最长的报文序列的长度。
- 本文引入编辑距离,来确定报文间的相似度。两个报文 和 之间的相似性得分 的计算式如式(1)所示:
- 集群内报文间结构相似性评分
- 在同一集群内,所有的报文应当具有相同的结构,在报文对齐阶段会尽可能少使用“-”符号。因此,本文使用平均每个集群中“-”符号的数量来确定结构相似度。(建议先从后往前,将同一集群公共的“-”去掉)
- 其中, 表示所有集群中“-”符号的总数量,N表示集群的数量。
- 在同一集群内,所有的报文应当具有相同的结构,在报文对齐阶段会尽可能少使用“-”符号。因此,本文使用平均每个集群中“-”符号的数量来确定结构相似度。(建议先从后往前,将同一集群公共的“-”去掉)
- 关键字位置字段评分
- 在客户端与服务端进行序列对齐后,分别根据上述两个度量指标选择得分最高的关键字,并计算字段偏移值 和 ,以及字段长度 和 。通过式(3)计算关键词位置字段评分。
- 在客户端与服务端进行序列对齐后,分别根据上述两个度量指标选择得分最高的关键字,并计算字段偏移值 和 ,以及字段长度 和 。通过式(3)计算关键词位置字段评分。
- 候选关键字作为实际关键字的概率为上述3个度量结果的乘积,数值最大的即为最可能的关键字。在关键字确定完成后,将关键字相同的报文聚类,并推断出协议的格式以及状态机模型。
- 报文相似度评分
- 协议格式推断方面,将同一个集群内的报文序列对齐后分别标记为动态字段以及静态字段,并记录其长度。
- 图5中的报文序列经过上述方法可以判断出f5为关键词,因此可以将报文聚类为两个集群。分别是集群1 : { mc0, mc2, mc3, mc4 }和集群2 : { mc1, mc5, mc6, mc7 }。
- 集群1的协议格式如图6所示。
3、基于模板的测试用例自动生成
- 协议程序往往对输入有着严格的校验,其通信过程如图7所示。
- 当协议程序收到一个外部输入时,首先会对输入进行解析,并依据规则进行匹配。如果解析之后匹配错误,输入会被直接拒绝并响应Error。在匹配成功后,根据输入数据字段匹配执行的功能,执行完成后向客户端发送相应的响应。
- 推断模板时,已经将字段分为静态字段以及动态字段。在测试用例生成时,不改变协议格式和静态字段或者进行微小的改动,防止模糊器发送的测试报文在开始阶段被待测程序拒绝。
- 根据缓冲区溢出、格式化字符串、整形溢出等漏洞的触发条件,在模板中定义如表1所列的测试用例的生成规则。
- 对于静态字段,在通信过程中几乎保持原值,但是该字段在解析异常情况下仍有触发漏洞的可能性,因此使用边界值对其进行填充。
- 对于动态字段,生成方式更加丰富,可以为模糊测试构建大量的测试报文。
- 文本类型动态字段:对分隔符进行替换、扩充以及减少操作;设置一个字典,用预定义的字符串如“true”、“play”、“%d”对其进行替换。
- 二进制类型动态字段:对长度较短的二进制字段进行逐位取反;对长度较长的二进制字段进行字节级的取反、右 移、与其他动态字段互换等操作。
- 由于漏洞的触发条件比较复杂,因此需要同时对多个不同的数据字段进行填充。上述的字段生成方案一次只填充一 个片段。然而,多字段变异在消息中随机选择一些动态字段,并对每个选择的字段执行上述生成方案。在接收到新的响应或目标协议程序崩溃之前,多字段变异将会一直进行下去。
4、状态迁移路径生成
- 当前的协议模糊测试工具难以测试到深层次的协议状态,且会忽略较长的协议状态迁移路径。在图1所示的协议状态机模型中,到达状态S3的状态迁移路径有L1以及L2。
- 状态迁移路径越长,需要发送和接收报文的时间开销就越大。大多数模糊测试工具倾向于发送 更快到达目标状态的报文序列,以减少消息的发送和接收时间。因此现有方法很难覆盖深层状态,同样也无法找到深层次路径下的bug。
- 因此,本文根据协议的状态机模型,首先对协议状态迁移路径进行删减,将几乎不可能存在漏洞的状态迁移路径删除,包括:直接迁移到终止状态的路径和回退到初始状态的路径。
- 根据上述方法删除图1中安全的状态迁移路径后得到如图8所示的状态机模型。
- 之后,本文基于深度优先算法遍状态机中的所有状态,得到完成的状态迁移路径。具体的测试路径生成算法如算法2所示。
- 算法2首先获取协议的初始以及终止状态,并将初始状态存放到状态迁移路径中,然后根据协议状态图遍历所有的协议状态。在遍历过程中,算法首先选择初始状态的后继状态,并判断此状态是否被遍历过。如果没有标记该状态,则算法会先标记该状态并将其放到状态会话链中,随后选择其后继状态。否则,算法将跳过此状态并重复迭代,直到后继状态 未标记。在终止状态遍历完成或不存在后继状态时完成遍历,获取到完成状态迁移路径。
- 图8中生成的两条状态迁移路径分别为:以及。
5、网络异常监测
- 此步骤用于探测目标程序是否存活,其通过监控设备的网络通信并设置超时,确定设备是否崩溃。
- 在超时的情况下,NAPfuzz将继续发送相同的消息序列3次,减少由网络波动而不是程序崩溃造成的误报。如果3次均超时,NAPfuzz将使用脚本重新启动测试程序,并再次发送相同的消息序列到测试程序。如果测试仍然没有按时返回消息,NAPfuzz将记录崩溃和相应的消息序列。
四、实验
- 本文根据上述模糊测试框架,构建了NAPfuzz。
1、实验设置
- 首先测试NAPfuzz协议格式逆向的准确性,然后与当前广泛使用的协议模糊测试工具Boofuzz和AFLnet进行对比。
- Boofuzz作为Sulley工作的继承,是一个基于生成的协议模糊测试工具,不过其没有协议逆向功能,需要手动定义协议的格式。本文将NAPfuzz的逆向结果输入Boofuzz,对比二者测试用例生成的数量,以及测试用例的质量。
- 此外,本文对真实的协议实体软件进行了测试,与Boofuzz和AFLnet进行了漏洞发现能力的对比实验。
2、格式准确性评估
- 本文选取广泛使用的网络协议RTSP和ICMP来测试NAPfuzz协议格式的逆向能力。推断出的协议报文格式以及实际的报文格式如图9所示。
- 图9(a)中,RTSP协议报文中Method被识别为动态字段;空白字段指包括“空 格”、“换行符”在内的分隔符,URL、版 本、首部字段名是固定的,因此被识别为静态字段;序列号的值是递增的动态字段;其他首部字段的值如session值是相同的,因此被识别为静态字段。
- 图9(b)中,ICMP协议报文中类型、校验和被识别为动态字段,代码、标识符、选项字段被识别为静态字段。
3、生成测试用例的数量以及准确性
- 本文将NAPfuzz与Boofuzz进行对比,通过比较相同时间内生成有效测试用例的数量以及所占比例来判断其测试用例的质量。图10给出了5h内NAPfuzz与Boofuzz生成的测试用例总数量以及有效测试用例(能够触发协议实体程序正常响应的测试用例)数量的情况。
- 从图10中可以看出,NAPfuzz生成的测试用例数量以及质量都优于Boofuzz。在5h内NAPfuzz生成的有效测试用例数量比Boofuzz提高了51.8%。
- 在测试时间超过4h后,NAPfuzz生成测试用例的速度加快,但是有效测试用例占比降低。这是由于测试后期进入多字段变异阶段,生成测试用例的数量增加,且其可能会破坏协议格式,造成无效的测试用例也增多。即便如此,NAPfuzz有效测试用例的数量以及比例依然高于Boofuzz。
4、漏洞发现能力评估
- 本文选取常用的有状态以及无状态网络协议实体程序作为测试对象。选择的具体协议及实体程序如表2所列。其中,FTP、RTSP和DNS都是经典的有状态网络协议,并且具有较为复杂的状态转换关系。HTTP作为无状态网络协议在现实世界中也有着广泛的应用。因此,本文选择上述协议的实体程序作为测试对象,来评估AFLnet、Boofuzz和NAPfuzz的漏洞发现能力。
- 对表2中的4个程序分别使用AFLnet、Boofuzz、NAP-fuzz测试24h后的漏洞发现情况如表3所列。
- 表3中,type表示漏洞的类型,detected表示是否检测到该漏洞,time表示发现该漏洞的时间,大于24h表示在测试的24h内没有发现该漏洞。
- 在漏洞发现数量上,NAPfuzz能够发现AFLnet和Boofuzz发现的所有历史漏洞,漏洞类型包括缓冲区溢出、格式化字符串、释放后重利用。在漏洞发现的时间上,NAPfuzz所用的时间都少于另外两种工具。并且还在aiohttp v3.8.1中发现了一个新的缺陷。
五、总结
- 本文研究网络协议模糊测试自动化生成符合协议规范的测试用例问题,提出了一种基于报文序列关键词的逆向方法,推断出协议格式以及状态机模型。
- 在模板中定义测试用例生成的规则以及报文的格式,生成器依据模板生成测试用例。
- 基于协议的状态机模型。使用深度优先算法生成测试路径,使模糊器尽可能测试到所有的状态,以及状态迁移路径。
- 实验结果表明,NAPfuzz可以生成高质量的测试用例,且能够有效地发现协议实体程序中的漏洞。本文的不足之处在于需要收集足够的通信流量,才能保证推断结果的准确性。 此外,本文方法无法应用于加密的协议。另一方面,本文实现的是一个黑盒协议模糊器,下一步将研究通过执行时的反馈信息对报文中不同的可变字段实现不同的变异策略,同时保留有价值的种子并对其进一步进行测试。
- 本文选取常用的有状态以及无状态网络协议实体程序作为测试对象。选择的具体协议及实体程序如表2所列。其中,FTP、RTSP和DNS都是经典的有状态网络协议,并且具有较为复杂的状态转换关系。HTTP作为无状态网络协议在现实世界中也有着广泛的应用。因此,本文选择上述协议的实体程序作为测试对象,来评估AFLnet、Boofuzz和NAPfuzz的漏洞发现能力。
- 本文将NAPfuzz与Boofuzz进行对比,通过比较相同时间内生成有效测试用例的数量以及所占比例来判断其测试用例的质量。图10给出了5h内NAPfuzz与Boofuzz生成的测试用例总数量以及有效测试用例(能够触发协议实体程序正常响应的测试用例)数量的情况。
- 本文根据上述模糊测试框架,构建了NAPfuzz。
- 协议程序往往对输入有着严格的校验,其通信过程如图7所示。
- NAPfuzz的目标是在没有协议先验知识的情况下,通过协议格式逆向技术构建模板,自动化生成符合协议规范的测试用例。依据协议状态机,生成覆盖所有协议状态的测试路径。最后基于网络流量探测,判断测试程序的异常状态。NAPfuzz的模糊测试流程如图3所示。
- 协议模糊测试工作流程如图2所示,主要包括预处理、变异策略选择、测试用例生成、模糊测试执行、异常判断和结果分析。
- 根据请求和响应数据是否独立,网络协议可以分为有状态协议和无状态协议。
- 模糊测试根据测试用例的生成方式可以分为基于突变的模糊测试技术和基于生成的模糊测试技术。