使用Peach進行模糊測試從入門到放棄

  • 2019 年 12 月 3 日
  • 筆記

概述

本文對模糊測試技術進行了綜述分析,介紹了開源模糊測試框架Peach的結構、原理及pit文件編寫方法,旨在幫助對模糊測試感興趣的小夥伴能快速入門peach,最後以常見的http協議和工控Modbus協議為例進行了實驗。文末搜集了本文所用到的工具和相關資料供大家下載。

模糊測試

概念

模糊測試 (fuzz testing, fuzzing)技術是安全測試技術的一種,通過構造畸形輸入數據使得軟體發生異常如崩潰等情況,從而發現軟體中存在的安全問題。由於模糊測試技術具有可以充分遍歷所有輸入數據、程式碼覆蓋全面、測試自動化、能夠有效地發現軟體中存在的安全問題等特點,受到資訊安全中漏洞分析領域的研究人員的廣泛歡迎。

目前,Fuzzing技術已經是軟體測試、漏洞挖掘領域的最有效的手段之一。Fuzzing技術特別適合用於發現0Day漏洞,也是眾多黑客或黑帽子發現軟體漏洞的首選技術。Fuzzing雖然不能直接達到入侵的效果,但是Fuzzing非常容易找到軟體或系統的漏洞,以此為突破口深入分析,就更容易找到入侵路徑,這就是黑客喜歡Fuzzing技術的原因。

原理

1、Fuzzing技術首先是一種自動化技術,即軟體自動執行相對隨機的測試用例。因為是依靠電腦軟體自動執行,所以測試效率相對人來講遠遠高出幾個數量級。比如,一個優秀的測試人員,一天能執行的測試用例數量最多也就是幾十個,很難達到100個。而Fuzzing工具可能幾分鐘就可以輕鬆執行上百個測試用例。 2、Fuzzing技術本質是依賴隨機函數生成隨機測試用例,隨機性意味著不重複、不可預測,可能有意想不到的輸入和結果。 3、根據概率論裡面的「大數定律」,只要我們重複的次數夠多、隨機性夠強,那些概率極低的偶然事件就必然會出現。Fuzzing技術就是大數定律的典範應用,足夠多的測試用例和隨機性,就可以讓那些隱藏的很深很難出現的Bug成為必然現象。

實現方法

Fuzzing引擎演算法中,測試用例的生成方式主要有2種:

1)基於變異:根據已知數據樣本通過變異的方法生成新的測試用例; 2)基於生成:根據已知的協議或介面規範進行建模,生成測試用例;

一般Fuzzing工具中,都會綜合使用這兩種生成方。基於變異的演算法核心要求是學習已有的數據模型,基於已有數據及對數據的分析,再生成隨機數據做為測試用例。

實現流程

一個基於網路協議的 Fuzz 測試的實現過程如下:

1 獲得待測協議的正常數據包 2 用變異數據替換該數據包中的某些部分 3 用發包器向目標應用發包 4 觀察目標應用的反應

通常情況下,通過抓包器捕獲客戶端與被測設備正常交互的數據包作為測試的正常數據包樣本。通過任意方式改變隨機數據。例如,可以打亂整個數據包,也可以把數據包中的某 個部分替換。不管採用什麼方法變異數據,關鍵是在數據包中放入大量隨機數據,然後將該數據包發送到目標應用並觀察目標應用的行為能力。

常用fuzz框架

在研究網路協議模糊測試時,sulley和peach兩大框架是最常見的Fuzz框架,peach相對於sulley有以下幾點優勢:

1、功能方面:sulley和peach完成的功能點都是一樣,peach可對多種協議、文件進行模糊測試,而sulley只能對網路協議進行測試。 2、開發角度:peach專註於xml文件的編寫,比較容易理解,但其餘部分幾乎很少能改寫;sulley用python程式碼來寫測試,可以開發一些插件、監視器等,適用於深度開發。 3、維護方面:sulley目前已停止維護,peach相關資料和研究人員相對較多。 4、安裝部署:sulley配置環境相對繁瑣,而peach配置環境相對簡單。

peach介紹

關於peach

Peach由Deja vu Security公司的Michael Eddington創造並開發,是一個遵守MIT開源許可證的模糊測試框架,是第一款綜合的開源fuzzing工具,包含進程監視和創建fuzzer,其中創建fuzzer由XML語言實現。Peach主要開發工作已經有7年了,主要有3個版本。最初採用Python語言編寫,發佈於2004年,第二版於2007年發布,Peach 3發佈於2013年初,第三版使用C#重寫了整個框架。

Peach支援對文件格式、ActiveX、網路協議、API等進行Fuzz測試;Peach Fuzz的關鍵是編寫Peach Pit配置文件。

安裝部署

Windows下使用Peach3需要預先安裝Microsoft.NET4和windbg;Linux、OS X下需要安裝Mono包。

Peach不是開源軟體,而是遵循MIT許可證的免費軟體。和BSD許可證一樣,MIT許可證在Peach的使用和修改上沒有限制。

我使用的windows綠色版,在[https://github.com/TideSec/Peach_Fuzzing/](https://github.com/TideSec/Peach_Fuzzing/)中peach文件夾中包含了收集到的4個版本的peach最新版軟體包,分別為windows版(x86)、windows版(x64)、oxs版、linux版、python版,大家可以下載使用。

體系結構

Peach模糊測試工具是一個開源的模糊測試框架,包括數據模型(數據類型、變異器介面等)、狀態模型(數據模型介面、狀態、動作—輸入輸出等)、代理器(包括本地調試器如WindowsDebugger和網路監視器如PcapMonitor等)、測試引擎(代理器介面、狀態模型介面、發布器、日誌記錄器等)

Peach有以下幾個高級概念:

1) 數據模型:用來表示輸入和輸出所需要的數據結構。可以根據需要構造數據模型。數據模型中,用戶可以設置數據變數,可以為該數據變數指定數據類型如字元串類型、整數類型等,還可以設置數據變數的數值,並根據變異器的介面指定該變數是否執行變異操作。數據模型中還可以設置數據塊,一個數據塊可以包括多個數據變數。數據變數之間還可以設置關係,例如size of類型的關係等。

2) 變異器:包括變異策略,不同數據類型的變異策略不同。

3) 生成器:Peach生成器能夠生成字元串數據、整型數值數據等簡單類型的數據,還可以生成複雜的分層的二進位數據,還可以將簡單的數據生成器串接起來生成更加複雜的數據類型的數據。

4) 狀態模型:在每一個測試用例中,根據狀態模型,Peach根據用戶配置初始化狀態機,並維護該有限狀態機,每個狀態包括一個或者多個操作。每個狀態中,Peach狀態機會順序地執行每個操作。用戶可以為操作設置相應的執行條件。當一個狀態中所有操作執行結束後還是維持當前狀態,則該狀態機執行結束。

5) 代理器:在Peach模糊測試過程中,Peach測試引擎與Peach代理器進行通訊,從而對被測目標進行狀態監視並對其進行執行控制。用戶必須為Peach代理器設置一個Peach監視器,從而對被測程式進行狀態監視,並進行執行控制如啟動被測程式或者停止被測目標程式。每次測試迭代或者測試子用例執行完畢,Peach代理器將把Peach監視器監視的被測目標程式的異常狀態資訊(如崩潰)返回給Peach測試引擎,如果被測目標程式正常執行結束,那麼將返回正常結束標誌資訊給Peach測試引擎。

6) 測試引擎:採用Peach解析器解析用戶輸入的配置文件(一般為pit格式的文件),根據配置文件創建相應的組件並進行初始化如對狀態模型的狀態機進行初始化,然後Peach測試引擎進入執行測試用例的主循環。測試引擎中的發布器可以對任意的生成器提供透明的介面,常見的發布器有文件發布器或者TCP網路發布器等,發布器是針對所生成的數據的一種傳輸形式。用戶(二次開發人員或使用人員)可以將自己的生成器連接到不同的輸出中。日誌記錄器可以設置日誌的路徑和文件名,並將測試執行過程中的狀態資訊記錄到日誌文件中。

使用流程

Peach 的測試對象幾乎包括了所有常見的Fuzz對象,例如文件結構,com,網路協議、API 等。

使用Peach進行fuzzing的主要步驟如下:

1、創建模型 2、選擇/配置Publisher 3、配置代理/監視器 4、配置記錄

命令參數

-1:執行第1次測試。-a:啟動Peach代理。不指定」channel」默認為本地代理(默認支援,無需顯式啟動);「channel」可以指定為」tcp」遠程代理。-c:統計測試用例數。-t:驗證Peach Pit xml文件正確性。-p:並行Fuzz。運行Peach的機器總數為M,這是第N個。–debug:調試資訊開關。–skipto:指定Fuzz跳過的測試用例數。–range:指定Fuzz的測試用例範圍

Pit文件

文件格式

Peach把用於數據定義的文件叫做Peach pit file。使用Peach時,實際上主要工作就是定義這樣一個xml文件指示Peach測試平台去做測試。Peach pit file基本上總是包含以下幾個部分:

<?xml...版本,編碼之類...>  <Peach ...版本,作者介紹之類...>  <Include ...包含的外部文件/>  <DataModel >原始數據結構定義</DataModel>  <StateModel >測試邏輯,狀態轉換定義,如收到什麼樣的數據包之後,發出什麼樣對應的數據包</StateModel>  <Agent >檢測 exception,crash 等 </Agent>  <Test >指定將要使用到的 state,agent,publisher 等</Test>  <Run >Fuzzer 執行的進入點</Run>  </Peach>

1)整個文件被一個大標籤包括。

2)文件中的第二級標籤包括 Include,DataModel,StateModel,Agent,Test,Run 共 6種。

3)Include 包含的外部文件,其中 defaults.xml 和 PeachTypes.xml 是必須的,裡邊含有Peach的基本方法、類、數據類型等。

4)DataModel 用於定義數據結構,此標籤下還可以有若干級、若干種下級標籤。使用這些子標籤可以比較容易的定義數據的類型,大小,各個數據塊之間的關係,以及 CRC 校 驗和等。還可以定義多個 DataModel,多個 DataModel之間可以有關係也可以沒有關係。

5)StateModel 用於定義測試的邏輯,實際上相當於一個狀態機。下級標籤包括 State, 每個 State 中又可以包含若干個 Action 標籤。State 表示一個狀態,不同的 State 之間可以根 據一些判斷條件進行跳轉。Action 用於執行打開文件,發送數據包之類的命令。

6)Agent 是一個主要功能是用來監測被測目標的反應,如 crash 等。

7)Test 這個標籤域比較簡單,一般只是制定使用哪個 Agent,哪個 StateModel,用什麼 方法發數據,有時還會指定使用什麼方法加工(變異)數據。

8)Run 這個標籤域也比較簡單,指定當前這次 Fuzz 測試使用哪個 Test。

Include配置

Include元素允許把其他pit文件包含到當前pit文件的名稱空間中使用。當引用被包含的Pit文件時,用名稱空間前綴和冒號的格式來命名。格式為:name:DataModel,如下所示:

屬性:

Ns—-必須的。名稱空間前綴。 Src—-必須的。源碼URL,用「file:」前綴來命名文件名。

DataModel配置

Peach Pit文件包含至少一個DataModel元素,DataModel描述的數據包括類型資訊、關係資訊(大小、數目、偏移)和其他讓模糊器執行智慧變異的資訊。DataModel是Peach根元素的子元素之一,它通過添加子元素(比如Number、Blob或者String)的方式定義了數據塊的結構。

屬性

Name—-必須的。當引用模型或者調試時,友好的DataModel名字是非常有用的。 Ref—-可選的。引用一個DataModel模板。 Mutable—-可選的,默認為真。該元素是否可變異。 Constraint—-可選的。確定一個表達式,它幫助Peach確定數據元素是否已被適當的消耗。

子元素

Block、Choice、Custom、Flag、Flags、Number、Padding、String、XmlAttribute、XmlElement、Relation、Fixup、Transformer、Placement

一個名字為「HelloTide」的DataModel包含一個字元串和輸出「Hello Tide!」如下所示:

一個DataModel可以引用其他DataModel,可以繼承帶有ref屬性的子元素。如下所示:

StateModel配置

StateModel重新創建測試一個協議所必須的基本狀態機器邏輯。它定義了怎麼給目標發送和接收數據。StateModel的範圍從非常簡單到及其複雜。建議在開始時,保持狀態模型簡單,需要時再進行擴展。

StateModel包含一個子元素state,state封裝了一個為Peach工作的邏輯單元,進而來執行一個大的狀態模型。state由action組成,每個action可以執行與單個狀態如何封裝邏輯相關的任務。

Action元素能在StateModel中執行多種操作。Action是發送命令給Publisher的一種主要方式,它能發送輸出,接收輸入或打開一個連接。Action也能在StateModel中改為其他狀態,在DataModel之間移動數據,調用被代理定義的方法。

Agent配置

代理是特殊的Peach進程,它可以在本地或者遠程運行。這些進程擁有一個或者多個監視器,這些監視器可以執行載入調試器,查看記憶體消耗或者探測錯誤等操作。代理中的監視器可以收集資訊和代表fuzzer執行操作。

常用的代理有:本地代理、TCP遠程代理、ZeroMQ、REST Json代理,其中前兩種使用頻率更高。

本地代理

Peach運行時支援一個運行在進程中的本地代理。如果不指定的話,這是一個默認的代理類型。配置一個本地代理如下:

TCP遠程代理

這個代理存活在本地或遠程機器的一個單獨的進程中,通過TCP遠程完成連接,是一種被本地運行時支援的RPC形式。為了使用遠程代理,代理進程必須首先運行起來。

代理配置

在遠程主機上運行peach.exe -a tcp

Monitor配置

Monitor主要有以下幾種監視器:windows監視器、OSX監視器、Linux監視器和跨平台監視器,每個平台的監視器都分很多種。

其中windows監視器包括:Windows Debugger Monitor、cleanup registry monitor、pageheap 監視器、PopupWatcher 監視器、windowsService 監視器等

OSX監視器包括:CrashWrangler 監視器、CrashReporter Monitor

Linux監視器包括:LinuxCrash

跨平台監視器包括:canakit relay 監視器、Cleanup Folder監視器、IpPower9258監視器、記憶體監視器、Pcap監視器、Ping監視器、進程監視器、Processkiller 監視器、保存文件監視器、socket 監視器、ssh監視器、ssh下載器監視器、vmware 監視器等。

官方文檔如下:

以幾個常見的為例進行參考。

Windows Debugger Monitor

WindowsDebugger監視器控制了一個windows調試句柄。主要有以下用途:進程調試、服務調試、內核調試。

必須參數

Commandline---用逗號分隔的窗口名字。Processname---當找到一個窗口的時候,觸發錯誤,默認為假。Kernelconnectionstring---內核調試的連接字元串。Service---要掛載的windows服務名稱。如果停止或者崩潰,服務將會被啟動。

可選參數

Symbolspath---符號表路徑或者服務。默認為:「SRV*http://msdl.microsoft.com/download/symbols」Windbgpath---windbg的安裝路徑。盡量在本地。Noncrystalline---直到從狀態模型的匹配調用完成時,debugger才會被掛載。Ignorefirstchanceguardpage---忽略第一個機會機會保護頁面錯誤。這些有時是假陽性或反調試錯誤。默認為假。Ignoresecondchanceguardpage---忽略第二個機會保護頁面錯誤。這些有時是假陽性或反調試錯誤。默認為假。Nocpukill---不要使用進程CPU使用率提前終止。默認為假。Faultonearlyexit---如果進程存在,觸發錯誤。默認為假。Waitforexitoncall--如果時間間隔到了,-等待狀態模型調用的進程退出和參數故障。Waitforexittimeout---等待退出,timeout值單位為微秒。(-1位無窮大)默認位10000。Restaroneachtest---為每次迭代重啟進程。默認為假。

其他參數示例

CrashWrangler 監視器

CrashWangler監視器將啟動一個進程和監視器感興趣的崩潰。這個監視器採用蘋果系統自帶的CrashWrangler工具,這個工具能從開發者網站下載。為了該工具能夠正常運行,它必須在每個機器上進行編譯。

參數:

Command---要執行的命令。Arguments---命令行參數,可選,默認沒有。StartOnCall---狀態模型調用的啟動命令。可選,默認沒有。UseDebugMalloc---使用OSX Debug Malloc(比較慢),可選默認為假。ExecHandler---Crash Wrangler 執行處理程式,可選,默認為exc_handler。ExploitableReads---讀a / v被認為是可利用的?可選,默認為假。NoCpuKill---通過CPU使用禁用進程殺死。可選,默認為假。CwLogFile---CrashWrangler記錄文件。可選,默認為cw.log。CwLockFile---CrashWrangler鎖文件,可選,默認為cw.lock。CwPidFile---CrashWrangler PID文件,可選,默認為cw.pid。

LinuxCrash監視器

LinuxCrash監視器用一個腳本來捕捉錯誤進程,該腳本被內置在內核中。

參數:

Executable---目標可執行程式,被用於過濾崩潰,可選的,默認為所有。LogFolder---記錄文件的文件夾。可選默認為「/var/peachcrash」。Mono---mono執行=程式所需的運行時的全路徑。可選,默認為「/usr/bin/mono」

Test配置

指定使用哪個Agent、StateModel,Publisher用什麼方法發送數據,使用什麼方法變異數據,日誌文件路徑等。可以有多個Test,使用時通過peach命令行指定要運行的Test名稱,未指定默認運行名稱為」Default」的Test。如下圖:

屬性:

Agent(可選)  StateModel(必須)  Publisher(必須)  Include(可選)  Exclude(可選)  Strategy(可選)  Logger(可選,推薦)

‍有效子元素:

Agent(可選)  StateModel(必須)  Publisher(必須)  Include(可選)  Exclude(可選)  Strategy(可選)  Logger(可選,推薦)

示例:

Loggers配置

Peach有一個可擴展的記錄系統,它允許使用者存儲他們想要的記錄。默認情況下,Peach使用一個單獨的文件系統記錄器。

Strategy配置

Strategy(變異策略)包括:

Random:默認會隨機選擇最大6個元素(可以通過參數MaxFieldsToMutate設置)利用隨機mutator(變異器)進行變異。

Sequential:Peach會順序對每個元素使用其所有可用的Mutators進行變異。

RandomDeterministic:Peach默認規則。這個規則對pit xml文件中元素根據Mutators生成的Iterations鏈表做相對隨機(由鏈表中元素數目決定)的順序混淆,所以每個xml文件每次運行生成的測試用例多少、順序固定,這樣才能保證skipto的準確性。

Peach3包括元素增、刪、改、交換,經驗值,逐位、雙字等Mutators。

示例運行

根據上述pit參數,做了個HelloTide的示例,了解pit文件基本的參數配置及結構。

HelloTide的pit文件已上傳github:[https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/HelloTide.xml](https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/HelloTide.xml)

<?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="TheDataModel">          <String value="Hello Tide!" />      </DataModel>        <StateModel name="State" initialState="State1" >          <State name="State1"  >              <Action type="output" >                  <DataModel ref="TheDataModel"/>              </Action>          </State>      </StateModel>          <Test name="Default">          <StateModel ref="State"/>          <Publisher class="Console" />          <Logger class="File">              <Param name="Path" value="log.txt" />          </Logger>          </Test></Peach>

在cmd中運行peach.exe samplesHelloTide.xml,運行後Peach會以這個原始的字元串 為模板變異出許多畸形的數據出來,包括了超長串、NULL結束符缺失的非法串、格式化串等有可能引起程式出錯的串,然後依次列印出來。

Log日誌記錄如下

peach應用——HTTP協議模糊測試

有些peach教程都是對圖片或者音影片文件進行fuzz,作為web狗只是對HTTP協議比較熟,所以嘗試對http進行peach模糊測試。

測試目的

本測試主要是測試 HTTP 協議的健壯性,通過訂製Peach pit file,查看是否可以通過對http協議進行模糊測試導致http服務不響應或其他異常現象。

選擇的目標是之前寫的一個掃描器登錄介面[https://github.com/TideSec/WDScanner](https://github.com/TideSec/WDScanner),使用phpstudy搭建。因為主要是測試http協議,所以任意web應用都可以。

分析協議

既然要進項協議fuzz,那麼首先應該搞清楚和伺服器之間的通訊協議是怎麼樣的。隨意下載一個可以在應用層進行抓包的軟體就可以滿足我們的需求,在此我用的是wireshark。

抓取登錄數據包:

http請求包

訂製pit文件

針對Http協議,完善pit文件httpfuzz.xml

httpfuzz的pit文件已上傳github:[https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/httpfuzz.xml](https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/httpfuzz.xml)

<?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="DataLogin">          <String value="GET /index.php?m=login" mutable="false" token="true"/>          <String value=" HTTP/1.1" />   <!-- 不加mutable="false" 說明要對該數值進行fuzz -->          <String value="rn" />            <String value="Content-Type: " mutable="false" token="true"/>          <String value="application/x-www-form-urlencoded" mutable="false" token="true"/>          <String value="rn" mutable="false" token="true"/>            <String value="Accept-Encoding: " mutable="false" token="true"/>          <String value="gzip, deflate" mutable="false" token="true"/>          <String value="rn" mutable="false" token="true"/>            <String value="Accept: " mutable="false" token="true"/>          <String value="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3" mutable="false" token="true"/>          <String value="rn" mutable="false" token="true"/>            <String value="User-Agent: " mutable="false" token="true"/>          <String value="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" mutable="false" token="true"/>          <String value="rn" mutable="false" token="true"/>            <String value="Host: 10.211.55.2" mutable="false" token="true"/>          <String value="rn" mutable="false" token="true"/>            <String value="Conection: " mutable="false" token="true"/>          <String value="Keep-Alive" mutable="false" token="true"/>          <String value="rn" mutable="false" token="true"/>        </DataModel>          <StateModel name="StateLogin" initialState="Initial">          <State name="Initial">              <Action type="output">                  <DataModel ref="DataLogin"/>              </Action>          </State>      </StateModel>          <Test name="Default">            <StateModel ref="StateLogin"/>          <Publisher class="TcpClient">              <Param name="Host" value="10.211.55.2"/>              <Param name="Port" value="80"/>          </Publisher>            <Logger class="File">              <Param name="Path" value="C:peachlogs"/>          </Logger>            <Strategy class="Sequential" />        </Test>   </Peach>

在該pit文件中,針對數值HTTP/1.1rn進行模糊測試,模糊策略為Sequential。

執行測試

在cmd中執行peach.exe sampleshttpfuzz.xml

測試結果

在wireshark中可看到發送的數據包,peach自動對HTTP/1.1rn生成了大量fuzz數據。

在使用過程中,也可對peach加參數-debug進行調試模式,可直接看到發送的數據包。

他山之石

在查閱各種資料中,發現我上面的寫法比較簡單粗暴,在網上找到一個實現比較優雅的http fuzz的Pit文件。

httpfuzz1的pit文件已上傳github:[https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/httpfuzz1.xml](https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/httpfuzz1.xml)

<?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/peach.xsd"><DataModel name="Headermodel">      <String name="Header" />      <String value=": "/>      <String name="Value" />      <String value="rn" /> </DataModel><DataModel name="HttpRequest">      <Block name= "RequestLine">          <String name="Method"/>          <String value=" "/>          <String name="RequestUri"/>          <String value=" "/>          <String name="HttpVersion"/>          <String value="rn"/>      </Block>        <Block name="HeaderHost" ref="Headermodel">          <String name="Header" value="Host" />      </Block>        <Block name="HeaderContentLength" ref="Headermodel">          <String name="Header" value="Content-Length" />          <String name="Value">              <Relation type="size" of="httpBody.content"/>          </String>      </Block>        <Block name="httpBody">          <String name="content" value="length is 12" />      </Block> </DataModel>       <Data name="HttpGet" >      <Field name="RequestLine.Method" value="GET"/>      <Field name="RequestLine.RequestUri" value="http://10.211.55.2" />      <Field name="RequestLine.HttpVersion" value="HTTP/1.1"/>      <Field name="HeaderHost.Value" value="http://10.211.55.2"/>      <Field name="httpBody.content" value="rnfuzz"/>   </Data>     <Data name="HttpOptions" ref="HttpGet">      <Field name="RequestLine.Method" value="OPTIONS"/>      <Field name="RequestLine.RequestUri" value="*" />      <Field name="HeaderHost.Value" value="" />   </Data>     <StateModel name="State1" initialState="Initial">      <State name="Initial">          <Action type="output">              <DataModel ref="HttpRequest"/>              <Data ref="HttpGet"/>          </Action>      </State> </StateModel> <StateModel name="State2" initialState="Initial">      <State name="Initial">          <Action type="output">              <DataModel ref="HttpRequest" />              <Data ref="HttpOptions" />          </Action>      </State> </StateModel><Test name="Default">          <StateModel ref="State1"/>            <Publisher class="TcpClient">                  <Param name="Host" value="10.211.55.2" />                  <Param name="Port" value="80" />          </Publisher>          <Logger class="File">              <Param name="Path" value="C:peachlogs"/>          </Logger></Test></Peach>

效果和上面類似,數據畸變更明顯,大家可以自己體驗一下。

測試結論

可惜的是運行了很大一會,並沒發現什麼畸形數據能導致http服務宕掉,返回的數據包基本也都是400錯誤。

peach應用——工控協議模糊測試

對modbus協議的模糊測試參考了2019年10月世界資訊安全大會中燈塔實驗室的幾位工控大佬的授課內容,在此表示由衷感謝!

我們Tide安全團隊的另外一個小夥伴也寫了篇關於工控模糊測試的文章,也可以參考[https://mp.weixin.qq.com/s/h9JWw1lZpfCmlQYZbBJIYA](https://mp.weixin.qq.com/s/h9JWw1lZpfCmlQYZbBJIYA)

工控協議里modbus算是最為常見的了,關於modbus協議相關的資料以及比較多了,就不重複介紹了,不太熟悉的可以參考[https://www.cnblogs.com/luomingui/archive/2013/06/14/Modbus.html](https://www.cnblogs.com/luomingui/archive/2013/06/14/Modbus.html)

在對modbus協議有了一定認識之後,我們開始對modbus協議進行fuzz測試。

搭建環境

理論上來講,應該使用真實的工控plc設備來進行實驗,因為模擬軟體對這種畸形的modbus協議是不會處理的,而真實的設備可能會因為無法響應請求而導致設備宕掉。但因為比較窮,手頭沒有設備,所以還是只能用模擬器了。

modbus模擬軟體+採集軟體下載:[https://github.com/TideSec/Peach_Fuzzing](https://github.com/TideSec/Peach_Fuzzing)

在一台虛擬機上打開modbus模擬軟體,模擬modbus服務(相關軟體在文末提供下載)

在自己電腦上打開採集器

分析數據

在採集器連接到模擬器時,使用wireshark可抓取到modbus協議數據

在任一modbus協議數據包上點右鍵,複製hex流

導出的數據為190000000006010100000064,這也是modbus協議的報文格式。

配置pit

modbus fuzz的pit文件已上傳github:[https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/modbus.xml](https://github.com/TideSec/Peach_Fuzzing/blob/master/pit-xml-samples/modbus.xml)

<?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="send_data">    <Block name="mod">     <Number name="01" size="16" value="19 00" valueType="hex" signed="false" mutable="false"/>     <Number name="02" size="16" value="00 00" valueType="hex" signed="false" mutable="false"/>     <Number name="03" size="16" value="00 06" valueType="hex" signed="false" mutable="false"/>     <Number name="04" size="16" value="01 01" valueType="hex" signed="false"/>  <!-- 不加mutable="false" 說明要對該數值進行fuzz -->     <Number name="05" size="16" value="00 00" valueType="hex" signed="false"/>     <Number name="06" size="16" value="00 64" valueType="hex" signed="false"/>    </Block>   </DataModel>     <StateModel name="TheState" initialState="initialState">     <State name="initialState">      <Action type="output">        <DataModel ref="send_data" />      </Action>    </State>   </StateModel>     <!--使用socket進行監聽埠 -->   <Agent name="Local">    <Monitor class="Socket">     <Param name="Host" value="10.211.55.6" />     <Param name="port" value="502" />    </Monitor>   </Agent>     <!--log保存-->   <Test name="Default">    <Agent ref="Local" />    <StateModel ref="TheState" />    <Logger class="File">     <Param name="Path" value="C:peachlogs" />    </Logger>      <Publisher class="tcp.Tcp">     <Param name="Host" value="10.211.55.6" />     <Param name="Port" value="502" />    </Publisher>     </Test></Peach>

執行測試

在cmd中執行peach.exe -debug samplesmodbus.xml,使用了debug模式。

查看數據

在wireshark中對數據包進行抓取,發現很多畸變數據

因為在pit文件中指定了只是對後面三組數據進行fuzz,所以前12位是不變的。

針對單個功能碼的fuzz數據

服務端被修改後的數據

16進位的2401轉換為10進位為9217。

測試結論

由於模擬器只能接受固定的協議格式和數據類型,所以對畸形的協議和數據都無法響應,所以還是沒能找到「設備」的modbus協議實現缺陷。但在對某些功能碼進行fuzz測試時,發現還是能偶爾成功更改服務端數據的。

為了提高測試的效率,對於協議安全性的測試可以只測試我們感興趣的有特殊意義的欄位,而不需要把每個欄位都進行測試。這樣可以避免做無用功,可以在有限的時間內完成最有效的測試。

總結

peach模糊測試可以用於對文件、ActiveX控制項、網路協議等進行安全測試,發現其存在的畸形輸入數據導致的格式錯誤或者應用邏輯錯誤等。但這要求對待測協議非常熟悉,掌握它的文件格式或報文規範,這樣才能寫出正確高效的peach pit文件。

寫pit文件這個過程要非常有耐心和細緻,而且初期失敗率極高且找不出來原因,如果不是為了寫這篇文章,我可能放棄peach很多次了,的確不太適合我這種只會用啊D的web腳本小子,還是放棄吧。。。

最後把本文涉及的所有軟體和文獻資料都打包放到了Gayhub上,地址奉上:[https://github.com/TideSec/Peach_Fuzzing](https://github.com/TideSec/Peach_Fuzzing)

參考文章

從互聯網上查閱了很多資料,感謝大佬們的無私奉獻。

peach比較推薦的資料是《peach框架模糊測試英文文檔》,這是官方指南,最權威的peach使用解讀,[https://github.com/TideSec/Peach_Fuzzing](https://github.com/TideSec/Peach_Fuzzing)上面已提供原版和中文版。 Fuzzing技術解讀與工具列表:https://blog.csdn.net/wcventure/article/details/82085251 Fuzzing技術總結:https://zhuanlan.zhihu.com/p/43432370 基於Peach的Modbus協議模糊測試:https://mp.weixin.qq.com/s/h9JWw1lZpfCmlQYZbBJIYA peach-fuzz:http://blog.nsfocus.net/peach-fuzz/ 深入探究文件Fuzz工具之Peach實戰:https://www.freebuf.com/sectool/120650.html 用peach對modbus協議進行模糊測試:https://www.freebuf.com/articles/security-management/88249.html 基於Peach的工業控制網路協議安全分析:http://jst.tsinghuajournals.com/CN/rhhtml/20170110.htm