<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Fuzzm: 針對WebAssembly內存錯誤的模糊測試

    VSole2022-06-01 16:31:17

    WebAssembly程序在JavaScript圈非常的火,可以大大加快瀏覽器的加載速度。但是WebAssembly的二進制程序通常由內存不安全的語言編譯而成,例如C和C++,而且由于WebAssembly屬于線性內存和缺乏保護的功能。

    一些源碼級別的內存漏洞可以在編譯的WebAssembly二進制文件里邊利用。而Fuzzm是第一個針對WebAssembly的模糊測試工具。

    作者在github上開源了這款工具,本文詳細介紹Fuzzm的配置流程。

    背景介紹

    看到了一篇對Web的WebAssembly程序的進行fuzzing的論文。

    相信有許多的大佬已經十分熟悉模糊測試和WebAssembly了,這里還是簡單介紹一下背景知識,這樣會更有連貫性。

    WebAssembly程序

    webAssembly是一種新型的能夠運行在現代web瀏覽器中運行的代碼。這是一種低級的壓縮的二進制格式的類匯編語言,能以近乎native的性能運行并且提供將c/c++、c#、Rust等高級語言編譯為可以運行在web端的目標版本;它也被設計為允許與JavaScript一起運行。

    WebAssembly已經被收錄為W3C WebAssembly Community Group的開放標準,使用WebAssembly JavaScript API,你可以通過它們加載WebAssembly模塊到一個Web App(node和JavaScript)中并且在兩者間共享功能。

    需要注意的是WebAssembly并不是真正的匯編語言。所以不能像真正的匯編語言一樣在真實的物理機上運行,總而言之,它是一個概念機上的機器語言。

    正因如此,WebAssembly 指令有時候被稱為虛擬指令。它比 JavaScript 代碼更快更直接的轉換成機器代碼,但它們不直接和特定硬件的特定機器代碼對應。

    在瀏覽器下載WebAssembly后,使 WebAssembly 的迅速轉換成目標機器的匯編代碼。

     

    如圖所示,如果想在頁面上添加WebAssembly,需要將代碼編譯成.wasm文件。

    使用WebAssembly,可以更快地在 web 應用上運行代碼。這里有 幾個 WebAssembly 代碼運行速度比 JavaScript 高效的原因:

    文件加載 - WebAssembly 文件體積更小,所以下載速度更快;

    解析 - 解碼 WebAssembly 比解析 JavaScript 要快;

    編譯和優化 - 編譯和優化所需的時間較少,因為在將文件推送到服務器之前已經進行了更多優化,JavaScript 需要為動態類型多次編譯代碼;

    重新優化 - WebAssembly 代碼不需要重新優化,因為編譯器有足夠的信息可以在第一次運行時獲得正確的代碼;

    執行 - 執行可以更快,WebAssembly 指令更接近機器碼;

    垃圾回收 - 目前 WebAssembly 不直接支持垃圾回收,垃圾回收都是手動控制的,所以比自動垃圾回收效率更高。

    模糊測試AFL

    模糊測試(fuzz testing, fuzzing)是一種軟件測試技術。

    其核心思想是將自動或半自動生成的隨機數據輸入到一個程序中,并監視程序異常,如崩潰,斷言(assertion)失敗,以發現可能的程序錯誤,比如內存泄漏。模糊測試常常用于檢測軟件或計算機系統的安全漏洞。

    模糊測試誕生于1988年秋季的一個黑暗暴風雨之夜 [Takanen et al, 2008.]。巴頓·米勒教授坐在麥迪遜威斯康星州的公寓里,通過一條1200波特的電話線連接到他所屬大學的計算機。

    陣陣的雷暴在線路上造成噪音,這些噪音又導致兩端的UNIX命令獲得錯誤的輸入,并導致崩潰。頻繁的崩潰使他感到驚訝—我們編寫的程序不是應該十分強大嗎?作為一名科學家,他想探究該問題的嚴重程度及其原因。

    因此,他為威斯康星大學麥迪遜分校的學生編寫了一個編程練習,而該練習將使他的學生創建第一個模糊測試器。

    這項作業的原文描述是這樣的:

    The goal of this project is to evaluate the robustness of various UNIX utility programs, given an unpredictable input stream. […] First, you will build a fuzz generator. This is a program that will output a random character stream. Second, you will take the fuzz generator and use it to attack as many UNIX utilities as possible, with the goal of trying to break them.

    該項目的目標是在給定不可預測的輸入流的情況下評估各種UNIX實用程序的健壯性。[…]首先,您將構建一個模糊發生器。這是一個將輸出隨機字符流的程序。其次,您將使用模糊發生器,并使用它來攻擊盡可能多的UNIX實用程序,以試圖破壞它們。

    這個作業在不經意間抓住了模糊測試的本質:創建隨機的輸入,并持續性觀察它是否會破壞目標應用程序,理論上只要運行足夠長的時間,我們就會看到錯誤的發生。

    AFL(american fuzzy lop)最初由Micha? Zalewski開發,和libFuzzer等一樣是基于覆蓋引導(Coverage-guided)的模糊測試工具,它通過記錄輸入樣本的代碼覆蓋率,從而調整輸入樣本以提高覆蓋率,增加發現漏洞的概率。其工作流程大致如下:

    1 從源碼編譯程序時進行插樁,以記錄代碼覆蓋率(Code Coverage)

    2 選擇一些輸入文件,作為初始測試集加入輸入隊列(queue)

    3 將隊列中的文件按一定的策略進行“突變”

    4 如果經過變異文件更新了覆蓋范圍,則將其保留添加到隊列中

    5 上述過程會一直循環進行,期間觸發了crash的文件會被記錄下來

    Fuzzm

    基于AFL模糊測試的原理,作者提出了首款針對WebAssembly的程序。測試原理如下圖所示:

    首先,針對原始的.wasm二進制文(Original Binary)件,由于其為線性內存,, 我們可以在WebAssembly程序中添加Stack & Heap Canaries(堆棧檢測點),用于檢測WebAssembly程序是否發生內存溢出錯誤, wasm二進制程序也變成了Hardened Binary。

    根據之前AFL的知識,我們知道灰盒測試(Greybox Fuzzing)之所以有效是因為它依賴于程序執行期間的輕量級反饋來引導AFL的執行, 為了收集該反饋,AFL會進行編譯插裝來跟蹤路徑覆蓋的的近似形式(approximate form of path coverage), 然后存儲在跟蹤位數組(trace bits array)中。

    由于WebAssembly屬于二進制程序,無法訪問源碼, 所以Fuzzm通過在所有的程序分支中插入代碼來提取與AFL兼容的覆蓋信息, 即instrument Approx Coverage。

    最后Fuzzm對AFL進行了高度優化,因此可以在wasm虛擬機上對程序進行模糊測試。

    開始運行

    說了這么多前導知識,那么我們現在就開始Fuzzm的配置安裝吧,首先我們從github網站上把這個項目拉下來。https://github.com/fuzzm/fuzzm-project

    由于要從外網下載各種配置資源,所以這里建議大家kexueshangwang。

    5.1 安裝各種環境

    1. 下載 Rust 和 cargo
    curl https://sh.rustup.rs -sSf | sh
    

    默認選1即可:

    下載完成后,輸入以下命令:

    source $HOME/.cargo/env
    

    下載 wasmtime:

    curl https://wasmtime.dev/install.sh -sSf | bash
    

    構建 wasmtime:

    git clone --recurse-submodules \    https://github.com/bytecodealliance/wasmtime.git
    

    之后開始構建wasmtime:

    cd wasmtimecargo build --release
    

    經過漫長的等待后構建完成,當然,,網速快的除外。:

    將程序連接到全局:

    sudo ln -s /home/mzs/Desktop/fuzzm-project/wasmtime/target/release/wasmtime /usr/bin/wasmtime
    

    從Ubuntu軟件源安裝Node.js 和 npm

    sudo apt updatesudo apt install nodejs npm
    

    配置完成,輸入nodejs --version 和 npm --version查看版本:

    下載 wasi sdk:

    wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-11/wasi-sdk-11.0-linux.tar.gztar xvf wasi-sdk-11.0-linux.tar.gz
    

    在fuzzm-project目錄下 執行npm install。

    5.2 開始配置

    進入 AFL-wasm文件夾:

    make & make install
    

    配置完成后, 使用afl-fuzz發現有以下錯誤:

    這是因為系統沒有找到對應的庫文件. 我們使用以下命令鏈接即可:

    sudo ln /path/to/fuzzm-project/AFL-wasm/wasmtime-v0.20.0-x86_64-linux-c-api/lib/libwasmtime.so /usr/lib/libwasmtime.so
    

    注意,下載路徑要配套, 庫文件的地址是你下載項目的位置。

    然后我們在運行afl-fuzz,情況已經正常:

    進入wasm_instrumenter文件夾:

    cargo build --release
    

    這個文件夾可以對wasm進行insert canaries 和 instrument coverage操作, 耐心等上一段時間, 配置完成后:

    開始鏈接到全局:

    sudo ln -s /home/mzs/Desktop/fuzzm-project/wasm_instrumenter/target/release/afl_branch /usr/bin/afl_branch sudo ln -s /home/mzs/Desktop/fuzzm-project/wasm_instrumenter/target/release/canaries /usr/bin/canaries
    

    5.3 開始fuzz

    a. 進入 motivating-example 文件夾

    我們可以看到這里有一段實例代碼:

    我們先對現成的wasm程序進行模糊測試。

    chmod +x vuln-cov-canaries.wasm WASM_MODE=1 afl-fuzz -i testcases/ -o output_cov_canaries ./vuln-cov-canaries.wasm
    

    b. 編譯項目,進入 benchmarks/openjpeg文件夾:

    ./wasm-compile-and-instrument.shcd bin/WASM_MODE=1 afl-fuzz -i ../tests/ -o output_canaries ./opj_compress.instr.wasm
    

    c. 將c文件轉化為wasm,并進行fuzz。

    我們以vuln.c 文件為例,首先我們從motivating-example文件夾中,,拷貝testcases 和 vuln.c,然后輸入以下命令::

    ../wasi-sdk-11.0/bin/clang --sysroot=../wasi-sdk-11.0/share/wasi-sysroot -O2 -D USE_JPIP=1 vuln.c -o vuln.wasm
    

    將c文件轉化為wasm文件。

    之后進行insert canaries 和 instrument coverage操作, 注意生成文件后使用chmod +x xxx.wasm授權。

    afl_branch vuln.wasm vuln.instr.wasm canaries vuln.instr.wasm vuln-cov-canaries.wasm
    

    然后開始fuzzing:

    WASM_MODE=1 afl-fuzz -i testcases/ -o outputs ./vuln-cov-canaries.wasm
    

    如何將項目轉化為wasm?

    這里我們以benchmarks/openjpeg為例。進入文件夾,,打開wasm-compile.sh文件。

    可以看到:想要轉化為wasm文件,需要將所有的依賴文件轉化過去。

    webassembly模糊理論
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    正因如此,WebAssembly 指令有時候被稱為虛擬指令。模糊測試AFL模糊測試是一種軟件測試技術。模糊測試常常用于檢測軟件或計算機系統的安全漏洞。陣陣的雷暴在線路上造成噪音,這些噪音又導致兩端的UNIX命令獲得錯誤的輸入,并導致崩潰。作為一名科學家,他想探究該問題的嚴重程度及其原因。最后Fuzzm對AFL進行了高度優化,因此可以在wasm虛擬機上對程序進行模糊測試。
    不幸的是,“軟件供應鏈安全指南”再次強化了這種謬誤。該指南要求集中化管理的安全團隊對軟件工程活動施加重大限制,從而實現“將安全作為重中之重”。為了安全起見,速度甚至可靠性都被視為合理的“傷亡代價”。對于政府情報部門而言,國家安全是主要使命,因此他們認為安全摩擦和障礙是值得的。該指南明確表示不鼓勵開源軟件。事實上,為了推銷廠商的安全產品,指南甚至給出了諸如手動發布流程之類的危險建議。
    不存在“超范圍”的滲透測試觀念Web應用程序已經變得非常復雜,會涉及較廣泛的資源和資產整合與利用。開發人員可能認為這些資產“超范圍”,因此不需要對它們負責。應用系統開發人員應該更好地與安全測試人員合作,減少滲透測試工作帶來的流程影響。跨站腳本攻擊不可忽視XSS屬于被動式攻擊,是一種較盛行的Web應用程序漏洞利用方式。
    想要確保應用安全,開發人員必須在創造力和安全框架之間取得平衡。關聯業務邏輯與安全邏輯可收獲安全紅利。
    針對單體架構的應用,安全防護往往在邊界網關設備處。隨著業務需求的不斷變化以及技術的持續更新,企業應用開始從單體架構向微服務架構轉變。不同應用模塊可以根據業務規模進行動態擴縮容,與此同時,微服務應用也為API安全防護帶來了新的挑戰。
    2021 年 6 月 21 日,Scott Logic 發布了 2021 年 WebAssembly 用戶報告。報告中顯示 69% 的受訪者認為 Wasm 將對未來的 Web 開發產生非常大的影響,同時受訪者還預計 Wasm 將會對不同應用領域產生重要影響。
    更為復雜的是,Wasm模塊缺乏完整性檢查,實際上無法確定應用程序是否被篡改。為了幫助說明WebAssembly的安全弱點,斯圖加特大學和慕尼黑聯邦國防軍大學的一組學者在2020年進行了一項研究,發現了可用于寫入任意內存、覆蓋敏感數據和劫持控制流的安全問題。
    發布了該活動細節的網絡安全公司 Sucuri 表示,在其一位客戶每次導航到他們自己的 WordPress 門戶時,他們的計算機都顯著變慢后,它發起了一項調查。Sucuri 惡意軟件研究員 Cesar Anjos說: “一旦解碼,auto.js 的內容會立即顯示加密礦工的功能,當訪問者登陸受感染的站點時,該加密礦工就會開始挖礦。
    目前的檢測器以JavaScript為唯一的目標語言,然而忽略了WebAssembly可能帶來的攻擊。論文提出了第一個通過將計算的部分移動到WebAssembly中來逃避靜態JavaScript惡意軟件檢測的技術。技術的核心是將JavaScript中實現惡意行為的片段翻譯為WebAssembly。通過實驗評估,該方法可以有效逃逸最先進的基于學習的靜態惡意軟件檢測。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类