官术网_书友最值得收藏!

45.2 go-fuzz的初步工作原理

go-fuzz實際上是基于前面提到的老牌模糊測試項目afl-fuzz的邏輯設計和實現的。不同的是在使用的時候,afl-fuzz對于每個輸入用例(input case)都會創建(fork)一個進程(process)去執行,而go-fuzz則是將輸入用例中的數據傳給下面這樣一個Fuzz函數,這樣就無須反復重啟程序。

func Fuzz(data []byte) int

go-fuzz進一步完善了Go開發測試工具集,很多較早接受Go語言的公司(如Cloudflare等)已經開始使用go-fuzz來測試自己的產品以提高產品質量了。

go-fuzz的工作流程如下:

1)生成隨機數據;

2)將上述數據作為輸入傳遞給被測程序;

3)觀察是否有崩潰記錄(crash),如果發現崩潰記錄,則說明找到了潛在的bug。

之后開發者可以根據crash記錄情況去確認和修復bug。修復bug后,我們一般會為被測代碼添加針對這個bug的單元測試用例以驗證bug已經修復。

go-fuzz采用的是代碼覆蓋率引導的fuzzing算法(Coverage-guided fuzzing)。go-fuzz運行起來后將進入一個死循環,該循環中的邏輯的偽代碼大致如下:

// go-fuzz-build在構建用于go-fuzz的二進制文件(*.zip)的過程中
// 在被測對象代碼中埋入用于統計代碼覆蓋率的樁代碼及其他信息
Instrument program for code coverage

Collect initial corpus of inputs  // 收集初始輸入數據語料(位于工作路徑下的corpus目錄下)
for {
    // 從corpus中讀取語料并做隨機變化
    Randomly mutate an input from the corpus

    // 執行Fuzz,收集代碼覆蓋率數據
    Execute and collect coverage

    // 如果輸入數據提供了新的代碼覆蓋率,則將該輸入數據存入語料庫(corpus)
    If the input gives new coverage, add it to corpus
}

go-fuzz的核心是對語料庫的輸入數據如何進行變化。go-fuzz內部使用兩種對語料庫的輸入數據進行變化的方法:突變(mutation)和改寫(versify)。突變是一種低級方法,主要是對語料庫的字節進行小修改。下面是一些常見的突變策略:

  • 插入/刪除/重復/復制隨機范圍的隨機字節;
  • 位翻轉;
  • 交換2字節;
  • 將一個字節設置為隨機值;
  • 從一個byte/uint16/uint32/uint64中添加/減去;
  • 將一個byte/uint16/uint32替換為另一個值;
  • 將一個ASCII數字替換為另一個數字;
  • 拼接另一個輸入;
  • 插入其他輸入的一部分;
  • 插入字符串/整數字面值;
  • 替換為字符串/整數字面值。

例如,下面是對輸入語料采用突變方法的輸入數據演進序列:

""
"", "A"
"", "A", "AB"
"", "A", "AB", "ABC"
"", "A", "AB", "ABC", "ABCD"

改寫是比較先進的高級方法,它會學習文本的結構,對輸入進行簡單分析,識別出輸入語料數據中各個部分的類型,比如數字、字母數字、列表、引用等,然后針對不同部分運用突變策略。 下面是應用改寫方法進行語料處理的例子:

原始語料輸入:

`<item name="foo"><prop name="price">100</prop></item>`

運用改寫方法后的輸入數據例子:

<item name="rb54ana"><item name="foo"><prop name="price"></prop><prop/></item>
    </item>
<item name=""><prop name="price">=</prop><prop/> </item>
<item name=""><prop F="">-026023767521520230564132665e0333302100</prop><prop/>
    </item>
<item SN="foo_P"><prop name="_G_nx">510</prop><prop name="vC">-9e-07036514
    </prop></item>
<item name="foo"><prop name="c8">prop name="p"</prop>/}<prop name=" price">01e-6
    </prop></item>
<item name="foo"><item name="foo"><prop JY="">100</prop></item>8<prop/></item>
主站蜘蛛池模板: 澎湖县| 调兵山市| 江山市| 福鼎市| 达拉特旗| 怀化市| 南丰县| 凤阳县| 阿瓦提县| 教育| 翁源县| 工布江达县| 金川县| 万安县| 威信县| 沛县| 贺州市| 澜沧| 黑山县| 余庆县| 胶南市| 合阳县| 九龙县| 漯河市| 巴彦淖尔市| 延长县| 景洪市| 宜春市| 即墨市| 吐鲁番市| 长沙县| 宣化县| 多伦县| 南郑县| 五莲县| 乾安县| 东乌珠穆沁旗| 门头沟区| 桓仁| 新宾| 康定县|