歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

使用DeepState對API進行模糊測試(上)

來源:本站整理 作者:佚名 時間:2019-04-01 TAG: 我要投稿

DeepState是一個框架,它為C和c++開發人員提供了一個公共接口,用于各種符號執行和模糊引擎。用戶可以使用類似于Google Test的API編寫一個測試工具,然后使用多個后端執行它,而不必了解底層引擎的復雜性。它支持編寫單元測試和API序列測試,以及自動測試生成。
使用DeepState,我們就可以編寫一個紅黑樹(red-black tree)模糊器。之后只需付出較少的努力,就可以將其變成一個功能更加全面的測試生成器。 盡管DeepState模糊器不需要很多的編碼工作,但它支持回歸測試(regressiontest)的重放,以減少用于調試的測試用例的大小,以及多個數據生成后端,包括Manticore,angr,libFuzzer和AFL。使用符號執行,我們甚至發現了原始模糊忽略的人為引入的漏洞。
在此,我保證你閱讀完本文后,可以完全在自己的API中進行一次高質量的自動化測試。
背景信息
2013年,猶他州大學計算機系的John Regehr撰寫了一篇關于“如何實現ADT的模糊測試”的博客。John詳細地討論了一些一般性問題,比如代碼覆蓋率、測試代碼和差異測試。如果你尚未閱讀John的文章,那么我建議你現在就閱讀。
一般性的模糊測試很簡單,只需要有一個測試軟件,利用John的方法就可以在測試對象上提供一組函數或方法。我們在這篇文章中的運行示例是一個紅黑樹,不過,AVL樹、文件系統、內存存儲,甚至密碼庫都可以達到類似的測試目的。由于我們的目標是對軟件進行徹底的測試,而傳統的單元測試方法則是編寫一系列看起來像以下這樣的小函數。
result1 = foo(3, "hello");
result2 = bar(result1, "goodbye")
assert(result2 == DONE);
也就是說,每個測試都會按著這樣的步驟來進行:“先運行一些測試內容,然后檢查它是否和預期的是一樣的。”這種方法有兩個問題。首先,工作量很大。其次,這項工作的測試效果并不像你想象的那樣好,每個測試都只針對一個測試內容,如果測試的人沒有提前把潛在的問題考慮進去,那么測試過程也就會忽略這些問題。
而在模糊測試中,用隨機壞數據(也稱做 fuzz)攻擊一個程序,然后等著觀察哪里遭到了破壞。模糊測試的技巧在于,它是不符合邏輯的:自動模糊測試不去猜測哪個數據會導致破壞(就像人工測試員那樣),而是將盡可能多的雜亂數據投入程序中。由這個測試驗證過的失敗模式通常對程序員來說是個徹底的震撼,因為任何按邏輯思考的人都不會想到這種失敗。模糊測試是一項簡單的技術,但它卻能揭示出程序中的重要漏洞。它能夠驗證出現實世界中的錯誤模式并在您的軟件發貨前對潛在的應當被堵塞的攻擊渠道進行提示。
模糊測試通常被認為會生成文件或數據包,但它也可以生成測試軟件庫的API調用序列。
foo_result = NULL;
bar_result = NULL;
repeat LENGTH times:
   switch (choice):
      choose_foo:
         foo_result = foo(randomInt(), randomString());
         break;
      choose_bar:
         bar_result = bar(foo_result, randomString());
         break;
      choose_baz:
         baz_result = baz(foo_result, bar_result);
         break;
   checkInvariants();
也就是說,fuzzer先反復選擇要調用的隨機函數,然后調用所選擇的函數,測試期間可能會存儲結果,以便在以后的函數調用中使用。
John的帖子不僅提供一般性建議,還包含了紅黑樹的工作模糊器的鏈接。這個模糊器是有效的,它是一個很好的例子,說明了如何使用基于隨機值生成的可靠測試工具來真正測試API。但是,它也不是一個完全實用的測試工具。它雖然會生成輸入,并測試紅黑樹,但當模糊器發現漏洞時,它只會打印一個漏洞信息隨即便崩潰。你沒有學到任何東西,除了“你的代碼有一個漏洞”這樣的信息外,我們再也得不到任何有價值的信息。
理想情況下,模糊器會自動將失敗的測試序列存儲在一個文件中,最小化這些序列以簡化調試,并且可以在回歸套件中重放過去的失敗測試。編寫支持所有這些基礎設施的代碼很是枯燥(尤其是在C/ c++中),而且會顯著增加測試工作所需的工作量。另外處理類似捕獲斷言違規和硬崩潰的現象,以便在終止之前將測試編寫到文件系統,也很難做到。
AFL和其他常用的模糊器通常會提供這種功能,這使得模糊測試成為一種更實用的調試工具。不幸的是,這種模糊測試器并不便于測試API。它們通常會生成一個文件或字節緩沖區,并期望被測試的程序將該文件作為輸入。將一系列字節轉換為紅黑樹測試可能比重新編寫更有趣,但工作量也很大。你真正想要的是一個像GoogleTest這樣的單元測試框架,但它能夠改變測試中使用的輸入值。有很多很好的隨機測試工具,包括TSTL,但很少有復雜的工具以C / C ++為目標,而且據我所知,沒有一個工具允許你使用除了工具內置的隨機測試器之外的任何測試生成方法。這就是我們想要的GoogleTest,它能夠使用libFuzzer,AFL,HonggFuzz或生成數據。
DeepState
DeepState滿足了我以上提到的所有測試要求,甚至更多。將John的模糊器轉換為DeepState測試工具相對容易,可以在文件deepstate_harness.cpp中找到DeepState的主要更改項,總共5項:
1.刪除main并用一個已經命名的test (test (RBTree, GeneralFuzzer))替換它;
1.1DeepState文件可以包含多個名為test的測試,但是只有一個測試是可以用的;
2.只需在每個測試中創建一個樹,而不是使用一個外部循環來迭代每次影響單個樹的調用:
2.1與模糊測試循環不同,我的測試更接近于非常一般化的單元測試,即每個測試都會執行一個有趣的API調用序列;
2.2DeepState將處理運行多個測試,模糊或符號執行引擎將提供“外部循環”;
3.將每個API調用序列的長度固定為固定值,而不是隨機值。

[1] [2] [3] [4]  下一頁

【聲明】:黑吧安全網(http://www.gkrbnd.live)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        福彩原副主任