深入解析GitLab开源协议模糊测试工具Peach Fuzzer的构建与使用

本文详细介绍了GitLab开源的Peach协议模糊测试工具的构建过程,包括依赖环境配置、编译步骤及模板编写方法,并通过实际案例演示如何发现Savant Web Server的缓冲区溢出漏洞。

Life’s a Peach (Fuzzer): 如何构建和使用GitLab的开源协议模糊测试工具

2021年5月22日 · 2263字 · 11分钟阅读

动机 🔗

Peach协议模糊测试器曾是一款知名的协议模糊测试工具,其母公司Peach Tech于2020年被GitLab收购。虽然Peach Tech此前发布过社区版Peach模糊测试器,但缺少商业版的许多关键功能和更新。幸运的是,GitLab以"GitLab Protocol Fuzzer Community Edition"的名义开源了Peach的核心协议模糊测试引擎,允许任何人构建和部署它。为简便起见,我将这个新开源版本称为Peach Fuzzer。

作为一个早期项目,其构建过程复杂且文档不全。此外,首次使用者可能难以理解如何使用该模糊测试器。更重要的是,GitLab的开源版本仍然缺少重要的资源,如模糊测试模板,这意味着您必须自己编写模板。

为此,本文旨在演示Peach Fuzzer的端到端应用,从构建到部署。请关注后续文章,我将探讨使用Peach Fuzzer发现和利用漏洞的完整工作流程。

构建Peach Fuzzer 🔗

尽管Peach Fuzzer可以在Linux和Windows上构建,但在撰写本文时,Linux构建流程似乎已损坏。因此,我在Windows上为Windows构建了该应用程序。

我使用了最新版本的Windows 10专业版,尽管微软确实提供了方便的免费虚拟机。由于依赖项要求繁重,我强烈建议在新的虚拟机中构建Peach Fuzzer,以免弄乱您自己的常规设置。

依赖项 🔗

GitLab仓库上的现有文档列出了以下构建先决条件:

  • Python 2.7
  • Ruby 2.3
  • doxygen、java、xmllint、xsltproc
  • .NET Framework 4.6.1
  • 带有C++编译器的Visual Studio 2015或2017
  • TypeScript编译器(tsc) v2.8
  • Intel Pin

让我们逐一查看。

Python 2.7 🔗

是的,它已经过时了,但构建流程明确为2.7编写,与Python 3不兼容(我试过)。在https://www.python.org/downloads/release/python-2718/获取x86-64 MSI安装程序并安装 - 记得选择将其添加到PATH的安装选项!或者,如果您已经安装了Python 3,可以继续安装2.7,然后使用py -2.7 <PYTHON COMMANDS>运行Python。

Ruby 2.3 🔗

虽然文档推荐了一个过时的Ruby版本,但我安装Ruby 2.7.2-1 (x64)(来自RubyInstaller下载页面,不带DevKit)也没问题。记得选择将其添加到PATH的选项。虽然您不需要MSYS2工具链,但安装它也无妨。

java、xmllint、xsltproc 🔗

这是一个很长的列表,单独安装这些依赖项可能很繁琐。幸运的是,这些包大多可以通过Chocolatey Windows包管理器获得。首先按照https://chocolatey.org/install上的说明安装Chocolatey,然后在提升的PowerShell窗口中运行以下命令:

1
2
3
choco install jdk8
choco install xsltproc
choco install git

您还需要安装git以便稍后克隆Peach Fuzzer仓库。

doxygen 🔗

doxygen是一个特殊情况 - 您需要从https://www.doxygen.nl/download.html的安装程序安装它。之后,编辑PATH环境变量以包含C:\Program Files\doxygen\bin

.NET Framework 4.6.1、带有C++编译器的Visual Studio 2015或2017 🔗

这里事情变得有点复杂。尽管文档说明需要.NET Framework 4.6.1,但似乎也需要4.5.1以防止构建过程崩溃。由于最新版本的Visual Studio是2019,您无法直接下载Visual Studio 2017。转到此下载页面获取旧版本,并创建一个免费的Visual Studio Dev Essentials帐户来访问它。下载Visual Studio Community 2017(版本15.9)并开始安装。

您将被提示安装不同的开发人员组件。我选择了"Desktop development with C++“工作负载。此外,在"Individual components"下,我选择了.NET Framework 4.6.1和4.5.1 SDK及目标包。您可以在右侧边栏中看到我的安装组件列表以供参考。

TypeScript编译器 🔗

虽然tsc似乎默认安装在Node中(通过运行npx tsc),但您还需要全局安装它。在https://nodejs.org/en/安装Node的LTS版本,然后在提升的命令提示符中运行npm install typescript --global,您就全部设置好了!

Intel Pin 🔗

这是另一个棘手的问题。文档推荐v3.2 81205,但它太旧了,Intel页面不再列出它。您可以直接从以下链接之一下载:

由于您是为Windows构建,只需要Windows版本。打开zip文件并将pin-3.2-81205-msvc-windows文件夹复制到protocol-fuzzer-ce\3rdParty\pin

隐藏依赖项 🔗

Peach还需要一些依赖项才能工作,但文档中没有列出:

  • .NET Framework 4.5.1
  • WinDBG
  • WireShark
  • Visual C++ Redistributable for Visual Studio 2012 Update 4

.NET Framework 4.5.1可以按照上述方式通过Visual Studio安装。要安装WinDBG,请按照https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools上的说明操作。WireShark有一个标准安装程序,您可以毫无问题地使用。这将允许您使用Windows调试器和数据包监视器。

由于Peach Fuzzer使用!exploitable来分类崩溃,您需要从https://www.microsoft.com/en-us/download/details.aspx?id=30679安装特定版本的Visual C++ Redistributable for Visual Studio 2012 Update 4。我测试了其他版本,只有2012版本有效。

构建命令 🔗

最后,是时候构建了!克隆仓库并cd进入其中,运行python waf configure(或者在我的情况下是py -2.7 waf configure)。如果一切顺利,您应该看到这个:

如果构建失败,是时候开始调试了。我发现来自configure的错误消息很有帮助,因为大多数时候,失败是由缺少依赖项引起的。如果二进制文件被删除,您也可以使用Visual Studio安装程序修复您的安装。

配置后,运行python waf build。这将构建您的文档以及Windows x86和x64变体,位于protocol-fuzzer-ce\slag中。最后,运行python waf install以创建最终的二进制文件并输出到protocol-fuzzer-ce\output

由于我们没有指定安装的变体,安装程序将为x86和x64生成调试和发布版本的文件。在大多数情况下,您将希望使用x64的发布版本;这将是您的Peach目录。

运行Peach Fuzzer 🔗

编写模板 🔗

构建Peach Fuzzer后,是时候测试它的能力了。Peach Fuzzer是一个生成式模糊测试器 - 这意味着它从用户定义的模板生成测试用例。这对于高度结构化的文件类型或具有严格校验和格式的协议特别有用。

我将通过针对一个小测试案例运行我的模板来演示Peach Fuzzer的功能:通过HTTP请求对Savant Web Server 3.1进行远程缓冲区溢出。针对已知易受攻击的应用程序验证您的模板总是好的。尽管Peach Fuzzer的开源版本没有附带任何内置模板,但有一些相当好的模板(在Peach中称为Pits)可用,例如这个HTTP Pit。

在编写模板之前,我强烈建议阅读构建过程中在output\doc\sdk\docs中生成的"Peach Pro Developer Guide”。它提供了关于模板各个组件的详细信息,以及各种Peach二进制文件的参数和输入,这些我不会在本文中讨论。现在回到测试模板:

我将之前的HTTP Pit文件改编为一个通用的GET HTTP模板:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?xml version="1.0" encoding="utf-8"?>
<Peach xmlns="http://peachfuzzer.com/2012/Peach" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://peachfuzzer.com/2012/Peach ../peach.xsd">

    <DataModel name="GetRequest">
        <String value="GET " mutable="false" token="true"/> 
        <String value="/"/>             
        <String value=" HTTP/1.1" mutable="false" token="true"/>
        <String value="\r\n" mutable="false" token="true"/>

        <String value="User-Agent: " mutable="false" token="true"/>
        <String value="Mozilla/5.0"/>   
        <String value="\r\n" mutable="false" token="true"/>

        <String value="Host: ##HOST##:##PORT##" mutable="false" token="true"/>
        <String value="\r\n" mutable="false" token="true"/>

        <String value="Accept: " mutable="false" token="true"/>
        <String value="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"/>   
        <String value="\r\n" mutable="false" token="true"/> 
        
        <String value="Accept-Language: " mutable="false" token="true"/>
        <String value="en-us"/> 
        <String value="\r\n" mutable="false" token="true"/>

        <String value="Accept-Encoding: " mutable="false" token="true"/>
        <String value="gzip, deflate"/> 
        <String value="\r\n" mutable="false" token="true"/>

        <String value="Referer: " mutable="false" token="true"/>
        <String value="http://##HOST##/"/>  
        <String value="\r\n" mutable="false" token="true"/>     

        <String value="Cookie: " mutable="false" token="true"/>
        <String value=""/>
                
        <String value="Conection: " mutable="false" token="true"/>
        <String value="Keep-Alive" mutable="false" token="true"/>   
        <String value="\r\n" mutable="false" token="true"/>
        <String value="\r\n" mutable="false" token="true"/>
    </DataModel>    
    
    <DataModel name="GetResponse">
        <String value="" />
    </DataModel>

    <StateModel name="StateGet" initialState="Initial">
        <State name="Initial">
            <Action type="output">
                <DataModel ref="GetRequest"/>
            </Action>
            <Action type="input">
                <DataModel ref="GetResponse"/>
            </Action>
        </State>
    </StateModel>   

    <Agent name="LocalAgent">
        <Monitor class="WindowsDebugger" />
    </Agent>

    <Test name="Default">
        <StateModel ref="StateGet"/>
        <Agent ref="LocalAgent"/>
        <Publisher class="TcpClient">
            <Param name="Host" value="##HOST##"/>
            <Param name="Port" value="##PORT##"/>
        </Publisher>
        
        <Logger class="File">
            <Param name="Path" value="Logs"/>
        </Logger>
        <Strategy class="Sequential" />
    </Test> 
</Peach>

为了支持参数,Peach Pits还必须附带一个配置文件:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<PitDefines>
    <All>
        <String key="HOST" value="127.0.0.1" name="Host" description="服务器主机名或IP"/>
        <String key="PORT" value="21" name="Port" description="服务器端口号"/>
    </All>
</PitDefines>

之后,将http_get.xmlhttp_get.xml.config复制到{PEACH DIRECTORY}\bin\pits\Net\http_get.xml。您可以将文件夹从Net重命名为任何其他类别。注意:您的模板必须在pits的子文件夹中,否则它不会出现在Peach GUI中。

接下来,从Peach目录运行.\Peach.exe。这将在端口8888上启动Web界面并在浏览器中打开它。幸运的你!

配置模糊测试会话 🔗

我们快到了!继续从Exploit Database页面安装易受攻击的Savant版本。

接下来,转到Library,您应该看到您的HTTP Get模板列出。单击它以启动新的Pit配置。由于我们正在模糊测试Savant的Web服务器,将配置命名为Savant。

在下一个屏幕中,选择Variables。从这里,覆盖参数以匹配Savant将占用的主机和端口。

接下来,您需要添加Monitors。如果您直接从CLI运行Peach,这些已经在您的模板中定义。然而,Web界面似乎需要手动配置。让我们看看这样做的两个步骤:

第一步:添加一个代理。这默认为本地,意味着代理将在Peach实例本身中运行,而不是在不同的主机中。给它一个合理的名称,如LocalAgent。

第二步:添加一个监视器。由于我们想要监视Savant进程的崩溃,我们必须添加一个Windows Debugger监视器并将Executable参数设置为Savant.exe的路径。

Peach Fuzzer还附带了许多有用的监视器和自动化功能,如弹出窗口点击器(例如关闭注册提醒)和网络监视。目前,Windows Debugger就是您所需要的。

保存您的监视配置,然后转到Test执行测试运行。这将使用一个测试用例运行Savant以确保一切顺利。如果一切顺利,是时候运行您的模糊测试会话了!

运行模糊测试会话 🔗

返回主仪表板以启动您的会话。祝你好运!在Savant的情况下,只需几秒钟您就会遇到第一个故障(崩溃)!

Peach Fuzzer将使用WinDbg的!exploitable在Risk列中自动分类您的崩溃(在屏幕截图中,由于缺少2012 Redistributable依赖项,所有内容都是UNKNOWN,但如果安装了它,应该正确分类)。

您可以单击单个测试用例以查看崩溃的适当描述和内存。

您还可以下载导致崩溃的测试用例。如果我们检查Savant的测试用例,我们将看到Peach Fuzzer将GET /路径修改为GET ///////////… WinDBG输出还表明EIP已被覆盖。这样,我们已经证明模板可以通过模糊测试成功发现Savant中已知的请求头缓冲区溢出漏洞。现在去找到另一个目标!

结论 🔗

就免费和开源的基于模板的生成式模糊测试器而言,研究人员没有太多选择。最大的替代方案是Python的"Monsters Inc.“系列模糊测试器,即Sulley,后来的BooFuzz,以及现在的NCC Group的Fuzzowski。GitLab的开源Peach Fuzzer在可用性和复杂性方面向前迈出了一大步,尽管受到缺乏预构建模板的限制。如果您有以前购买Peach Fuzzer Professional的模板,您很幸运。然而,这些模糊测试器的秘密武器始终是模板。可悲的是,GitLab不会开源Pro模板,并且只会在今年晚些时候在商业产品后面提供它们。没有大型模板库,Peach Fuzzer的用处有限。

如果您愿意投入工作来构建自己的模板,我认为Peach Fuzzer是一个极好的入门工具包,可以让您进入模糊测试游戏。然而,当涉及到更高级的模糊测试时,Peach就力不从心了。虽然它声称是一个"智能"模糊测试器,但它是在模糊测试的旧时代记录的。更准确地说,它是一个基于预写模板进行模糊测试的生成式或文件格式感知模糊测试器。如今,覆盖引导/反馈驱动的模糊测试器,如AFL和Honggfuzz,可能被认为是更先进的方法。Peach只使用Intel Pin来最小化语料库,似乎不将其用于实际的模糊测试。

然而,Peach仍然在任何研究人员的工具包中占有一席之地,特别是如果您的重点是特定的文件结构。我发现Peach特别适用于原型化潜在的模糊测试目标,因为它设置快速且能够在没有harness的情况下模糊测试黑盒目标。它仍然可以捕获表面级别的漏洞,并帮助突出显示可能易受攻击的目标以进行更深入的模糊测试。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计