AFL(American Fuzzy Lop)變異策略

參考:http://lcamtuf.blogspot.com/2014/08/binary-fuzzing-strategies-what-works.html

變異策略決定了fuzzers的生存與死亡。如果對輸入文件的變異過於保守,則fuzzer的代碼覆蓋率有限。如果過於激烈,則大多數測試用例可能無法解析,浪費CPU時間。

下面來看一下具體的變異策略:

  • 位翻轉:AFL採用的第一個也是最基本的變異策略是順序執行的有序位翻轉。在一行中翻轉的位數從1到4。在一個龐大而多樣化的輸入語料庫中,得出了以下結論:

    翻轉一個位:生成的每百萬個輸入中有70條新路徑。

    翻轉兩個位:生成的每百萬個輸入中增加20條新路徑。

    翻轉四個位:生成的每百萬個輸入中增加10條新路徑

    (增加的路徑是在上一個策略中沒有發現的路徑)

    當然,這個策略的花費相對較高,輸入文件中每個字節的傳遞都需要8 個execve()。隨着回報快速減少,AFL會在這三次通過以後停止,並切換到第二個比較便宜的策略。

  • 字節翻轉:字節翻轉是位翻轉的擴展。這個方法主要是8,16,32位的寬字節翻轉。除了可以用較短的翻轉觸發的情況之外,這一策略生成的每百萬次輸入中增加約30條路徑。

    非常明顯的是,輸入文件每一個字節的傳遞只需要一個execve(),因此它的花費較少。但這也限制了絕對條件下它的潛在效率。

  • 簡單算術:爲了以確定性的方式去觸發更復雜的條件,在第三個階段,AFL嘗試在輸入文件中輕微的增加或減少現有的整數值。實驗選擇的操作範圍爲-35到+35,通過這個範圍,fuzzing區域大幅減少。

    這個策略包含3個步驟:首先,fuzzer嘗試對每個字節進行加法與減法操作。第二步是對16位進行遞增或遞減操作,但只有當這個操作會影響到最高有效字節時纔會進行(否則,就會重複第一步)。第三步操作與第二步類似,是對32位進行操作。

    這個策略的效果根據格式的不同而有所不同:從JPEG的每百萬個增加2條新路徑到xz的每百萬個增加8條新路徑。花費也相對較高,輸入文件中每個字節的傳遞大約需要20個execve()。

  • 已知整數:AFL採用的最後一個確定性方法依賴於一些可觸發邊緣條件的整數集(例如,-1,25,1024,MAX_INT-1,MAX_INT)。fuzzer使用端點值逐步對輸入文件中的現有數據進行覆蓋。

    這個策略每百萬個增加2到5條新路徑輸入文件中每個字節的傳遞大約需要30個execve()。

  • 堆調整:確定性策略耗盡以後,fuzzer會繼續執行一個無休止的隨機循環操作,該循環由以下堆序列組成:

    單個位翻轉,
    嘗試設置“有趣”的字節,單詞或雙字(兩個內部),(邊緣值)
    將小整數加到或減去字節,單詞或雙字(兩個末尾),
    完全隨機的單字節集,
    塊刪除,
    通過覆蓋或插入來阻止重複,
    memset()函數操作。(memset作用是在一段內存塊中填充某個給定的值)

    基於大量的測試,當每個操作執行的概率大致相同時,效果似乎最好。堆疊操作的數量被選爲1到64之間的二分之一; 並且塊操作的塊大小限制在大約1 kB。

    基於相當多的測試,當每個操作的概率大致相同時,似乎實現了最優的執行路徑收益; 堆操作的數量是1到64之間的二分之一; 並且塊操作的塊大小限制在大約1 kB。

    這一階段的所發現的路徑多於之前確定性策略的路徑和。

  • 測試集拼接:這是一個最後的策略,涉及從至少兩個位置不同的隊列中獲取兩個不同的輸入文件; 並在中間的隨機位置拼接它們,然後進行短時間的“堆調整”策略。 這個策略通常會發現之前策略中沒有觸發的執行路徑中的20%。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章