protocol-fuzzing/protocol-state-fuzzer

GitHub: protocol-fuzzing/protocol-state-fuzzer

一个模块化、可扩展的通用协议状态模糊测试框架,支持自动学习协议实现的状态机模型、执行测试序列以及计时分析。

Stars: 11 | Forks: 8

# ProtocolState-Fuzzer [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/26b85810e0024646.svg)](https://github.com/protocol-fuzzing/protocol-state-fuzzer/actions/workflows/ci.yml) ## 目录 * [描述](#description) * [前置条件](#prerequisites) * [安装说明](#installation) * [快速开始](#quick-start) * [学习](#learning) * [测试](#testing) * [计时](#timing) * [日志](#logging) * [资源文件](#resource-files) * [被使用于](#used-by) ## 描述 ProtocolState-Fuzzer 是一个_通用_、_模块化_且_可扩展_的协议状态模糊器, 可用作框架,用于对不同网络协议实现进行状态机学习和模糊测试。 ProtocolState-Fuzzer 为特定的协议客户端或服务器实现提供以下功能: 1. 学习实现的状态机模型。 2. 通过执行测试输入序列对实现进行测试。 3. 在测试输入序列上对实现进行计时,以建议超时值, 从而避免在学习或测试期间出现与时间相关的非确定性。 ## 前置条件 * Java 21 JDK。 * 正确配置 maven 以指向 Java 21 JDK。 * graphviz 库,包含 dot 实用程序,该程序应位于系统的 PATH 中。 ## 安装说明 假设命令是从根目录执行的: 1. 要检查前置条件,请使用: ``` java -version mvn -version dot -V ``` 2. 要安装 ProtocolState-Fuzzer,请使用: ``` mvn install ``` 此命令将: * 在 `target` 目录中创建包含已编译类的 **jar** 文件,并将其安装在本地 Maven 仓库中; * 在 `target` 目录中创建 **html** 和 **jar** 格式的 javadocs。**html** 页面将位于 `target/apidocs` 目录中, 可以使用 Web 浏览器查看。**jar** 格式将安装在本地 Maven 仓库中, 可在编程期间用于内联文档; * 在 `target` 目录中创建包含源文件的 **jar** 文件, 并将其安装在本地 Maven 仓库中。这可用于调试目的以及编程期间源代码的内联浏览。 ## 快速开始 一个主类可以如下所示: ``` public class Main { public static void main(String[] args) { // Multibuilder implements all necessary builders MultiBuilder mb = new MultiBuilder(); // single parentLogger, if Main resides in the outermost package String[] parentLoggers = {Main.class.getPackageName()}; CommandLineParser commandLineParser = new CommandLineParser<>(mb, mb, mb, mb); commandLineParser.setExternalParentLoggers(parentLoggers); List results = commandLineParser.parse(args, true); // further process the results if needed } } ``` 注意: * [CommandLineParser](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/entrypoints/CommandLineParser.java) 类是 ProtocolState-Fuzzer 的一个入口点。其构造函数需要一些构建器, 例如可以按照下面定义的 `MultiBuilder` 类来实现, 该类特定于 `MealyMachine` 模型。 * 当 Main 类位于最外层的包中时,*Main* 类的包名足以作为应用程序的 *外部父记录器*。`setExternalParentLoggers` 方法用于在遇到 `-debug` 或 `-quiet` 参数时,使应用程序的日志级别遵循 ProtocolState-Fuzzer 的日志级别。 * `CommandLineParser` 中有不同的 `parse` 方法,可以解析并执行提供的参数,将学习到的 `DOT` 文件导出为 `PDF`, 并对结果使用指定的 `Consumers`。上面使用的 `parse` 方法会将学习到的 `DOT` 文件导出为 `PDF`。 ``` public class MultiBuilder implements StateFuzzerConfigBuilder, StateFuzzerBuilder>, TestRunnerBuilder, TimingProbeBuilder { // InputImpl, OutputImpl, AlphabetPojoXmlImpl need to be implemented protected AlphabetBuilder alphabetBuilder = new AlphabetBuilderStandard<>( new AlphabetSerializerXml(InputImpl.class, AlphabetPojoXmlImpl.class) ); // ExecutionContextImpl, SULBuilderImpl need to be implemented protected SULBuilder sulBuilder = new SULBuilderImpl(); @Override public StateFuzzerClientConfig buildClientConfig() { return new StateFuzzerClientConfigStandard( new LearnerConfigStandard(), new SULClientConfigStandard(new MapperConfigStandard(), new SULAdapterConfigStandard()), new TestRunnerConfigStandard(), new TimingProbeConfigStandard() ); } @Override public StateFuzzerServerConfig buildServerConfig() { return new StateFuzzerServerConfigStandard( new LearnerConfigStandard(), new SULServerConfigStandard(new MapperConfigStandard(), new SULAdapterConfigStandard()), new TestRunnerConfigStandard(), new TimingProbeConfigStandard() ); } @Override public StateFuzzer> build(StateFuzzerEnabler stateFuzzerEnabler) { return new StateFuzzerStandard<>( new StateFuzzerComposerStandard<>(stateFuzzerEnabler, alphabetBuilder, sulBuilder).initialize() ); } @Override public TestRunner build(TestRunnerEnabler testRunnerEnabler) { return new TestRunnerStandard<>(testRunnerEnabler, alphabetBuilder, sulBuilder).initialize(); } @Override public TimingProbe build(TimingProbeEnabler timingProbeEnabler) { return new TimingProbeStandard<>(timingProbeEnabler, alphabetBuilder, sulBuilder).initialize(); } } ``` 注意: * [StateFuzzer](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/statefuzzer/core/StateFuzzer.java) 接口代表学习过程,并使用 [StateFuzzerStandard](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/statefuzzer/core/StateFuzzerStandard.java) 和 [StateFuzzerComposerStandard](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/statefuzzer/core/StateFuzzerComposerStandard.java) 实现。 * [TestRunner](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/statefuzzer/testrunner/core/TestRunner.java) 接口代表测试过程,并使用 [TestRunnerStandard](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/statefuzzer/testrunner/core/TestRunnerStandard.java) 实现。 * [TimingProbe](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/statefuzzer/testrunner/timingprobe/TimingProbe.java) 接口代表计时过程,并使用 [TimingProbeStandard](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/statefuzzer/testrunner/timingprobe/TimingProbeStandard.java) 实现。 ## 学习 在基于 ProtocolState-Fuzzer 和目标 SUL 设置好特定工具后, 可以使用参数文件或提供命令行参数来启动学习。 参数文件可以简单地包含命令行参数及其值。 也可以提供命令行参数来覆盖参数文件中的内容。 参数文件前面的 `@` 符号可以省略。 最简单的命令是: ``` java -jar specific-fuzzer.jar @path/to/argfile ``` 上述不带参数文件的命令将列出所有可用的命令行选项。 ## 测试 测试不仅需要参数文件,还需要测试序列,该序列通常存储在文件中。 测试序列文件可以每行包含一个输入符号。 测试命令为: ``` java -jar specific-fuzzer.jar @path/to/arg/file -test path/to/test/file [-additional_param] Additional Testing Parameters: -times N Run each test sequence N number of times, defaults to 1 -testSpecification path/to/dot/model If a .dot model is provided as a specification, the resulting outputs are compared against it. The test file will be run both on the implementation and on the specification model -showTransitionSequence Shows the sequence of transitions at the end in a nicer format ``` ## 计时 计时是测试的扩展,需要指定 `-test` 和 `-probeCmd` 参数。 它用于查找防止 SUL 产生非确定性输出的计时值。 它对 `-probeCmd` 中的所有命令使用相同的初始范围,并**仅**基于 `-test` 提供的测试执行搜索。 因此,对于学习而言,计时值可能需要进一步的手动调整。 计时探针命令为: ``` java -jar specific-fuzzer.jar @path/to/arg/file -test path/to/test/file -probeCmd [-additional_param] Available comma-separated probe commands: - responseWait (time to wait for an SUL response) - startWait (time to wait after starting the SUL) - (time to wait for the response of this alphabet input symbol) Example: -probeCmd responseWait,startWait,input1,input2 Additional Timing Parameters: -times N Run each test sequence N number of times, defaults to 1 -probeLow N The lowest non-negative integer probe timing value, defaults to 0 -probeHigh N The highest integer probe timing value, defaults to 1000 -probeTol N Search tolerance value that defines the desired precision, defaults to 10 Small tolerance values increase accuracy but may require more iterations -probeExport path/to/alphabet/out The output file for the alphabet augmented with timing values Useful when an input symbol has been provided in -probeCmd ``` ## 日志 ProtocolState-Fuzzer 的默认日志级别是 `ERROR`。更改它的一种方法是 通过 `log4j2.xml` 配置。[此处](src/test/resources/log4j2.xml)用于测试的配置示例将日志级别设置为 `TRACE`。 日志级别可以更改为: * `INFO`,以获得最少且足够的日志记录,或者 * `DEBUG`,以便同时记录交换的输入和输出消息 ## 资源文件 可以在 `src/main/resources` 目录中提供以下文件, 以便 ProtocolState-Fuzzer 能够发现它们。 * `default_alphabet.xml` **(必填)** 此文件充当默认字母表 文件,以防没有通过 `-alphabet` 参数指定其他字母表文件。此文件的模板位于[此处](src/test/resources/default_alphabet.xml), 可以使用 [AlphabetPojoXml](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/components/learner/alphabet/xml/AlphabetPojoXml.java) 的实现进行读取。 如果没有通过 `-alphabet` 参数指定字母表文件,并且在资源中找不到 `default_alphabet.xml`,则会发生致命异常, 因为无法构建字母表且进程无法继续。 * `default_fuzzer.properties` **(可选)** 它允许指定一些 可在参数文件中使用的属性。您可以在[此处](src/test/resources/default_fuzzer.properties)查看此文件的示例。 关于条目 `results.learning.clients=results/clients`,属性 `results.learning.clients` 可以在参数文件中写为 `${results.learning.clients}`, 以便将其解析为 `results/clients`。此外,JVM 属性 `-Dfuzzer.properties=file` 可用于加载特定的属性文件,而不是 `default_fuzzer.properties`,例如 `java -Dfuzzer.properties=file -jar ...`。 * `default_mapper_connection.config` **(可选)** 此文件允许为 特定的 mapper 指定一些配置选项。也可以使用 `-mapperConnectionConfig` 参数来使用其他配置文件代替默认文件。配置文件的输入流可以通过 [MapperConfig](src/main/java/com/github/protocolfuzzing/protocolstatefuzzer/components/sul/mapper/config/MapperConfig.java) 中的 `getMapperConnectionConfigInputStream()` 获取。 此文件的内容格式取决于用户。请注意,如果未通过 `-mapperConnectionConfig` 指定配置文件,并且在资源中 找不到 `default_mapper_connection.config`,则 `getMapperConnectionConfigInputStream()` 将返回 `null`。 ## 被使用于 * [BLE-Fuzzer](https://github.com/protocol-fuzzing/ble-fuzzer) * [DTLS-Fuzzer](https://github.com/assist-project/dtls-fuzzer) * [EDHOC-Fuzzer](https://github.com/protocol-fuzzing/edhoc-fuzzer) * [TCP-Fuzzer](https://github.com/protocol-fuzzing/tcp-fuzzer)
标签:CISA项目, Graphviz, Maven, 内存取证对抗, 协议安全评估, 协议实现分析, 协议状态模糊器, 域名枚举, 密码管理, 时间非确定性测试, 模块化架构, 模糊测试框架, 漏洞验证, 状态机学习, 网络协议分析, 网络协议模糊测试, 网络安全, 自动化状态机提取, 隐私保护