Metalnem/sharpfuzz

GitHub: Metalnem/sharpfuzz

将 AFL 模糊测试框架的覆盖引导能力引入 .NET 平台,通过 IL 插桩实现对托管程序集的自动化漏洞挖掘。

Stars: 450 | Forks: 37

# SharpFuzz:用于 .NET 的基于 AFL 的模糊测试 [![NuGet](https://img.shields.io/nuget/v/SharpFuzz.svg)][nuget-link] [![Build Status](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/4727c83626000451.svg)][build-link] [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)][license-link] SharpFuzz 是一款将 [afl-fuzz] 的强大功能 引入 .NET 平台的工具。如果您想了解更多关于模糊测试的内容、 我编写 SharpFuzz 的动机、它能够发现的 bug 类型、 或者关于如何与 afl-fuzz 集成的技术细节, 请阅读我的博客文章 [SharpFuzz: Bringing the power of afl-fuzz to .NET platform](https://mijailovic.net/2019/01/03/sharpfuzz/)。 ## 目录 - [CVE](#cve) - [文章](#articles) - [战利品](#trophies) - [环境要求](#requirements) - [安装](#installation) - [使用方法](#usage) - [高级主题](#advanced-topics) - [致谢](#acknowledgements) ## CVE - [CVE-2019-0980: .NET Framework and .NET Core Denial of Service Vulnerability](https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2019-0980) - [CVE-2019-0981: .NET Framework and .NET Core Denial of Service Vulnerability](https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2019-0981) - [CVE-2025-11573: Denial of Service issue in Amazon.IonDotnet](https://aws.amazon.com/security/security-bulletins/AWS-2025-022/) ## 文章 - [SharpFuzz: Bringing the power of afl-fuzz to .NET platform](https://mijailovic.net/2019/01/03/sharpfuzz/) - [Five years of fuzzing .NET with SharpFuzz](https://mijailovic.net/2023/07/23/sharpfuzz-anniversary/) - [Let’s do DHCP: fuzzing](http://writeasync.net/?p=5714) - [Fuzzing C# on Windows with SharpFuzz and libfuzzer-dotnet](https://github.com/ranweiler/libfuzzer-dotnet-windows-example/blob/main/README.md) - [Automate Bug Finding: Fuzzing C# Code on Windows](https://blog.objektkultur.de/Automate-Bug-Finding-Fuzzing-C-Sharp-Code-on-Windows/) - [Fuzzing .NET Libraries with AFL++ and SharpFuzz](https://allthingsreversed.io/20260308-fuzzing-dotnet-libraries.html) ## 战利品 如果您使用 SharpFuzz 发现了一些有趣的 bug, 并且愿意分享它们,我很乐意将它们 添加到此列表中。请给我发送电子邮件, 对 README 文件发起 pull request,或者提交一个 issue。 - [AngleSharp: HtmlParser.Parse 抛出 InvalidOperationException](https://github.com/AngleSharp/AngleSharp/issues/735) **已修复** - [AngleSharp: HtmlParser.ParseDocument 抛出 IndexOutOfRangeException](https://github.com/AngleSharp/AngleSharp/issues/1174) **已修复** - [AngleSharp: HtmlParser.ParseDocument 抛出 InvalidOperationException](https://github.com/AngleSharp/AngleSharp/issues/1176) **已修复** - [AngleSharp: HtmlParser.ParseDocument 永久挂起](https://github.com/AngleSharp/AngleSharp/issues/1179) **已修复** - [CoreFX: BigInteger.TryParse 越界访问](https://github.com/dotnet/corefx/issues/35176) **已修复** - [CoreFX: BinaryFormatter.Deserialize 抛出许多意外异常](https://github.com/dotnet/corefx/issues/35491) **已修复** - [CoreFX: DataContractJsonSerializer.ReadObject 抛出 ArgumentOutOfRangeException](https://github.com/dotnet/corefx/issues/35205) - [CoreFX: DataContractJsonSerializer.ReadObject 抛出 IndexOutOfRangeException](https://github.com/dotnet/runtime/issues/1410) - [CoreFX: DataContractSerializer.ReadObject 抛出 ArgumentNullException](https://github.com/dotnet/runtime/issues/1409) - [CoreFX: Double.Parse 在 .NET Core 3.0 上抛出 AccessViolationException](https://github.com/dotnet/corefx/issues/35780) **已修复** - [CoreFX: G17 格式说明符并不总能对 double 值进行往返转换](https://github.com/dotnet/corefx/issues/35369) **已修复** - [CoreFX: Uri.TryCreate 抛出 IndexOutOfRangeException](https://github.com/dotnet/corefx/issues/35072) - [CoreFX: XmlReader.Create 抛出 IndexOutOfRangeException](https://github.com/dotnet/corefx/issues/35073) **已修复** - [DotLiquid: Template.Parse 抛出 ArgumentNullException 而非 SyntaxException](https://github.com/dotliquid/dotliquid/issues/333) - [Esprima .NET: JavaScriptParser.ParseProgram 抛出 ArgumentOutOfRangeException](https://github.com/sebastienros/esprima-dotnet/issues/70) **已修复** - [Esprima .NET: 解析大量起始括号时出现 StackOverflowException](https://github.com/sebastienros/esprima-dotnet/issues/104) **已修复** - [ExcelDataReader: ExcelReaderFactory.CreateBinaryReader 可能抛出意外异常](https://github.com/ExcelDataReader/ExcelDataReader/issues/383) **已修复** - [ExcelDataReader: ExcelReaderFactory.CreateBinaryReader 抛出 OutOfMemoryException](https://github.com/ExcelDataReader/ExcelDataReader/issues/382) **已修复** - [ExCSS: StylesheetParser.Parse 抛出 ArgumentOutOfRangeException](https://github.com/TylerBrinks/ExCSS/issues/101) **已修复** - [Fluid: FluidTemplate.TryParse 和 FluidTemplateExtensions.Render 抛出一些意外异常](https://github.com/sebastienros/fluid/issues/148) **已修复** - [Fluid: FluidTemplateExtensions.Render 永久挂起](https://github.com/sebastienros/fluid/issues/149) **已修复** - [Google.Protobuf: MessageParser.ParseFrom 抛出意外异常 (C#)](https://github.com/protocolbuffers/protobuf/issues/5513) **已修复** - [GraphQL-Parser: Parser.Parse 解析 58K 文件耗时约 18 秒](https://github.com/graphql-dotnet/parser/issues/22) **已修复** - [GraphQL-Parser: Parser.Parse 抛出 ArgumentOutOfRangeException](https://github.com/graphql-dotnet/parser/issues/21) **已修复** - [Handlebars.Net: Handlebars.Compile 永久挂起](https://github.com/rexm/Handlebars.Net/issues/283) **已修复** - [Handlebars.Net: 模板引擎抛出一些意外异常](https://github.com/rexm/Handlebars.Net/issues/282) **已修复** - [Jil: JSON.DeserializeDynamic 抛出 ArgumentException](https://github.com/kevin-montrose/Jil/issues/316) **已修复** - [Jint: Engine.Execute 可能抛出许多意外异常](https://github.com/sebastienros/jint/issues/571) **已修复** - [Jint: Engine.Execute 耗时超过两分钟才能完成(即使设置了 2 秒超时)](https://github.com/sebastienros/jint/issues/586) **已修复** - [Jint: Engine.Execute 在 45 秒后抛出 OutOfMemoryException(即使设置了 2 秒超时)](https://github.com/sebastienros/jint/issues/587) **已修复** - [Json.NET: JsonConvert.DeserializeObject 可能抛出几种意外异常](https://github.com/JamesNK/Newtonsoft.Json/issues/1947) **[已修复](https://github.com/JamesNK/Newtonsoft.Json/pull/2922)** - [Jurassic: ScriptEngine.Execute 以 StackOverflowException 终止进程](https://github.com/paulbartrum/jurassic/issues/141) - [Jurassic: ScriptEngine.Execute 抛出一些意外异常](https://github.com/paulbartrum/jurassic/issues/142) **已修复** - [Jurassic: ScriptEngine.ExecuteFile 永久挂起,而不是抛出 JavaScriptException](https://github.com/paulbartrum/jurassic/issues/138) **已修复** - [Jurassic: ScriptEngine.ExecuteFile 抛出 FormatException](https://github.com/paulbartrum/jurassic/issues/137) **已修复** - [LumenWorks CSV Reader: CsvReader.ReadNextRecord 抛出 IndexOutOfRangeException](https://github.com/phatcher/CsvReader/issues/67) - [Markdig: Markdown.ToHtml 永久挂起](https://github.com/lunet-io/markdig/issues/278) **已修复** - [Markdig: Markdown.ToHtml 处理 32K 文件耗时超过两分钟](https://github.com/lunet-io/markdig/issues/306) **已修复** - [Markdig: Markdown.ToHtml 抛出 ArgumentOutOfRangeException](https://github.com/lunet-io/markdig/issues/275) **已修复** - [Markdig: Markdown.ToHtml 抛出 IndexOutOfRangeException](https://github.com/lunet-io/markdig/issues/276) **已修复** - [Markdig: Markdown.ToHtml 抛出 IndexOutOfRangeException](https://github.com/lunet-io/markdig/issues/303) **已修复** - [Markdig: Markdown.ToHtml 在 GetCurrentDefinitionList 中针对 lastBlock 抛出 IndexOutOfRangeException](https://github.com/xoofx/markdig/issues/839) **已修复** - [Markdig: Markdown.ToHtml 在 StringSlice.NextChar() 中抛出 IndexOutOfRangeException](https://github.com/xoofx/markdig/issues/840) **已修复** - [Markdig: Markdown.ToHtml 抛出 InvalidOperationException "A block is already being replaced"](https://github.com/xoofx/markdig/issues/841) **已修复** - [Markdig: Markdown.ToHtml 抛出 NullReferenceException](https://github.com/lunet-io/markdig/issues/277) **已修复** - [Markdig: 转换特殊 markdown 为 HTML 时抛出 StackOverflowException](https://github.com/xoofx/markdig/issues/497) **已修复** - [MarkdownSharp: Markdown.Transform 永久挂起](https://github.com/StackExchange/MarkdownSharp/issues/8) - [MemoryPack: AcessViolationException from MemoryPackReader.ReadString](https://github.com/Cysharp/MemoryPack/issues/306) - [MessagePack for C#: MessagePackSerializer.Deserialize 永久挂起](https://github.com/neuecc/MessagePack-CSharp/issues/359) **已修复** - [MessagePack for CLI: Unpacking.UnpackObject 抛出几种意外异常](https://github.com/msgpack/msgpack-cli/issues/311) - [Mono.Cecil: ModuleDefinition.ReadModule 可能抛出许多(可能)意外的异常](https://github.com/jbevain/cecil/issues/556) - [Mono.Cecil: ModuleDefinition.ReadModule 永久挂起](https://github.com/jbevain/cecil/issues/555) **已修复** - [NCrontab: CrontabSchedule.Parse 抛出 OverflowException 而不是 CrontabException](https://github.com/atifaziz/NCrontab/issues/43) - [nHapi: 错误输入导致意外异常和永久挂起](https://github.com/nHapiNET/nHapi/issues/196) **已修复** - [nHapi: 错误输入导致 StackOverflow/Access Violation](https://github.com/nHapiNET/nHapi/issues/198) **已修复** - [NoStringEvaluating: Evaluator.Calc 抛出几种意外异常](https://github.com/KovtunV/NoStringEvaluating/issues/14) **已修复** - [NUglify: Uglify.Js 永久挂起](https://github.com/xoofx/NUglify/issues/63) **已修复** - [Open XML SDK: 添加一些安全/模糊测试](https://github.com/OfficeDev/Open-XML-SDK/issues/441) - [OpenMCDF: 解析 Excel 文档时出现 OutOfMemoryException / 无限 while 循环](https://github.com/ironfede/openmcdf/issues/30) **已修复** - [OpenMCDF: System.ArgumentOutOfRangeException 再现](https://github.com/ironfede/openmcdf/issues/39) **已修复** - [OpenMCDF: 尝试打开某些无效文件时出现 System.ArgumentOutOfRangeException](https://github.com/ironfede/openmcdf/issues/38) **已修复** - [OpenMCDF: 读取损坏的 Word 文档时出现 System.OutOfMemoryException](https://github.com/ironfede/openmcdf/issues/40) **已修复** - [PdfPig: 读取损坏的 PDF 文档时出现 StackOverflowException](https://github.com/UglyToad/PdfPig/issues/33) **已修复** - [protobuf-net: Serializer.Deserialize 可能抛出许多意外异常](https://github.com/mgravell/protobuf-net/issues/481) - [protobuf-net: Serializer.Deserialize 永久挂起](https://github.com/mgravell/protobuf-net/issues/479) **已修复** - [Scriban: Template.ParseLiquid 抛出 ArgumentOutOfRangeException](https://github.com/lunet-io/scriban/issues/121) **已修复** - [Scriban: Template.ParseLiquid 抛出 NullReferenceException](https://github.com/lunet-io/scriban/issues/120) **已修复** - [Scriban: Template.Render 抛出 InvalidCastException](https://github.com/lunet-io/scriban/issues/122) **已修复** - [SharpCompress: 枚举 ZipArchive.Entries 集合抛出 NullReferenceException](https://github.com/adamhathcock/sharpcompress/issues/431) - [SharpZipLib: ZipInputStream.GetNextEntry 永久挂起](https://github.com/icsharpcode/SharpZipLib/issues/300) **已修复** - [SixLabors.Fonts: FontDescription.LoadDescription 抛出 ArgumentException](https://github.com/SixLabors/Fonts/issues/96) **已修复** - [SixLabors.Fonts: FontDescription.LoadDescription 抛出 NullReferenceException](https://github.com/SixLabors/Fonts/issues/97) **已修复** - [SixLabors.ImageSharp: 处理错误数据时在 Jpeg 位读取器中处理 EOF 以防止 DOS 攻击](https://github.com/SixLabors/ImageSharp/pull/2516) **已修复** - [SixLabors.ImageSharp: Image.Load 以 AccessViolationException 终止进程](https://github.com/SixLabors/ImageSharp/issues/798) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 AccessViolationException](https://github.com/SixLabors/ImageSharp/issues/827) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 ArgumentException](https://github.com/SixLabors/ImageSharp/issues/826) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 ArgumentOutOfRangeException](https://github.com/SixLabors/ImageSharp/issues/825) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 DivideByZeroException](https://github.com/SixLabors/ImageSharp/issues/821) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 DivideByZeroException](https://github.com/SixLabors/ImageSharp/issues/822) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 ExecutionEngineException](https://github.com/SixLabors/ImageSharp/issues/839) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 IndexOutOfRangeException](https://github.com/SixLabors/ImageSharp/issues/824) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 NullReferenceException](https://github.com/SixLabors/ImageSharp/issues/797) **已修复** - [SixLabors.ImageSharp: Image.Load 抛出 NullReferenceException](https://github.com/SixLabors/ImageSharp/issues/823) **已修复** - [Utf8Json: JsonSerializer.Deserialize 可能抛出许多意外异常](https://github.com/neuecc/Utf8Json/issues/142) - [Web Markup Minifier: HtmlMinifier.Minify 永久挂起](https://github.com/Taritsyn/WebMarkupMin/issues/73) **已修复** - [Web Markup Minifier: HtmlMinifier.Minify 抛出 InvalidOperationException](https://github.com/Taritsyn/WebMarkupMin/issues/77) **已修复** - [YamlDotNet: YamlStream.Load 解析 37K 文件耗时超过 60 秒](https://github.com/aaubry/YamlDotNet/issues/379) - [YamlDotNet: YamlStream.Load 以 StackOverflowException 终止进程](https://github.com/aaubry/YamlDotNet/issues/375) - [YamlDotNet: YamlStream.Load 抛出 ArgumentException](https://github.com/aaubry/YamlDotNet/issues/374) ## 环境要求 AFL 可在 Linux 和 macOS 上运行。如果您使用的是 Windows,可以使用任何 适用于 [Windows Subsystem for Linux] 的 Linux 发行版。如需原生 Windows 支持您可以使用 [libFuzzer](https://github.com/Metalnem/sharpfuzz/blob/master/docs/libFuzzer.md) 来代替 AFL。 您需要 GNU make 和一个可用的编译器 (gcc 或 clang)才能编译 afl-fuzz。 您还需要在计算机上安装 [.NET 8.0] 或更高版本,以便使用 SharpFuzz 对 .NET 程序集进行插桩。 为了简化您的模糊测试体验,也建议 安装 [PowerShell]。 ## 安装 您可以通过运行以下 [脚本] 来安装 afl-fuzz 和 [SharpFuzz.CommandLine] 全局 .NET 工具: ``` #/bin/sh set -eux # 下载并解压最新的 afl-fuzz 源代码包 wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz tar -xvf afl-latest.tgz rm afl-latest.tgz cd afl-2.52b/ # 安装 afl-fuzz sudo make install cd .. rm -rf afl-2.52b/ # 安装 SharpFuzz.CommandLine global .NET tool dotnet tool install --global SharpFuzz.CommandLine ``` ## 使用方法 本教程假设您对 afl-fuzz 有一定程度的了解。 如果您对此一无所知, 应该先阅读 [AFL quick start guide] 和 [afl-fuzz README]。如果您有足够的时间,我也 建议阅读 [Understanding the status screen] 和 [Technical whitepaper for afl-fuzz]。 作为示例,我们将对 [Jil] 进行模糊测试, 这是一个快速的 JSON 序列化器和反序列化器 (更多完整的模糊测试项目示例请参见 [SharpFuzz.Samples])。 **1.** 创建一个新的 .NET 控制台项目,然后通过运行以下命令向其中添加 [Jil] 和 [SharpFuzz] 包: ``` dotnet add package Jil dotnet add package SharpFuzz ``` **2.** 在您的 **Main** 函数中,使用您想要测试的函数作为参数调用 **SharpFuzz.Fuzzer.OutOfProcess.Run**: ``` using System; using System.IO; using SharpFuzz; namespace Jil.Fuzz { public class Program { public static void Main(string[] args) { Fuzzer.OutOfProcess.Run(stream => { try { using (var reader = new StreamReader(stream)) { JSON.DeserializeDynamic(reader); } } catch (DeserializationException) { } }); } } } ``` 我们想要对 Jil 的反序列化能力进行模糊测试, 这就是为什么我们要调用 **JSON.DeserializeDynamic** 方法。输入数据将通过 **stream** 参数提供给我们 (如果您测试的代码将输入作为字符串接收, 您可以使用 **Fuzzer.OutOfProcess.Run** 的另一个重载, 它接受 **Action<string>**)。 如果传递给 **Fuzzer.OutOfProcess.Run** 的代码抛出异常, 它将作为崩溃报告给 afl-fuzz。然而, 我们只想将*意外*异常视为 bug。 **DeserializationException** 是我们在 遇到无效 JSON 输入时所预期的,这就是为什么我们 在示例中捕获了它。 **3.** 创建一个包含一些测试用例的目录(通常 一个测试就足够了)。测试文件 应包含一些被您的代码接受为有效的输入, 并且应尽可能小。例如,这是我用于 测试 JSON 反序列化器的 JSON: ``` {"menu":{"id":1,"val":"X","pop":{"a":[{"click":"Open()"},{"click":"Close()"}]}}} ``` **4.** 假设您的项目名为 ```Fuzzing.csproj``` 且您的测试用例位于 ```Testcases``` 目录中。 通过像这样运行 [fuzz.ps1] 脚本开始模糊测试: ``` pwsh scripts/fuzz.ps1 Jil.Fuzz.csproj -i Testcases ``` 对于 HTML、JavaScript、JSON 或 SQL 等格式, 使用 [字典] 文件可以极大地改善模糊测试过程。 AFL 附带了许多字典, 安装后您可以在 ```/usr/local/share/afl/dictionaries/``` 中找到它们。 考虑到这一点,我们可以像这样改进对 Jil 的模糊测试: ``` pwsh scripts/fuzz.ps1 Jil.Fuzz.csproj -i Testcases \ -x /usr/local/share/afl/dictionaries/json.dict ``` **5.** 休息一下吧!您通常会在几分钟内 得到一些有用的结果,但有时 可能需要超过一天的时间,所以请耐心等待。 导致未处理异常的输入文件将 出现在 ```findings/crashes``` 目录中。 唯一崩溃的总数将以红色显示在 afl-fuzz 状态屏幕上。 实际上,真正唯一的异常数量往往 低于报告的数量,这就是为什么通常 最好编写一个小程序,仅遍历 崩溃输入,对每个输入运行模糊测试函数, 并仅保存产生唯一堆栈跟踪的输入。 ## 高级主题 - [模糊测试 .NET Core](https://github.com/Metalnem/sharpfuzz/blob/master/docs/fuzzing-dotnet-core.md) - [进程外模糊测试](https://github.com/Metalnem/sharpfuzz/blob/master/docs/miscellaneous.md#out-of-process-fuzzing) - [测试用例最小化](https://github.com/Metalnem/sharpfuzz/blob/master/docs/miscellaneous.md#test-case-minimization) - [配合 SharpFuzz 使用 libFuzzer](https://github.com/Metalnem/sharpfuzz/blob/master/docs/libFuzzer.md) - [旧版使用说明](https://github.com/Metalnem/sharpfuzz/blob/master/docs/legacy-usage-instructions.md) ## 致谢 - **Joe Ranweiler** 和 MORSE 团队 - [Windows 上的 libFuzzer 支持](https://github.com/Metalnem/sharpfuzz/pull/24) - **Michal Zalewski** - [american fuzzy lop](http://lcamtuf.coredump.cx/afl/) - **Dmitry Vyukov** - [go-fuzz: randomized testing for Go](https://github.com/dvyukov/go-fuzz) - **Rody Kersten** - [Kelinci: AFL-based fuzzing for Java](https://github.com/isstac/kelinci) - **Jb Evain** - [Mono.Cecil](https://github.com/jbevain/cecil) - **0xd4d** - [dnlib](https://github.com/0xd4d/dnlib) - **Guido Vranken** - [go-fuzz: libFuzzer support](https://github.com/dvyukov/go-fuzz/pull/217)
标签:AFL, AI合规, ASN解析, CVE, Fuzzing, SharpFuzz, 多人体追踪, 安全测试, 拒绝服务, 攻击性安全, 数字签名, 测试工具, 渗透测试辅助, 紫队, 覆盖率引导