# [Efficient Greybox Fuzzing of Applications in Linux-Based IoT Devices via Enhanced User-Mode Emulation](https://dl.acm.org/doi/abs/10.1145/3533767.3534414) ## Abstract * 灰盒 Fuzzing 是漏洞挖掘的主流方法,但因 IoT 的環境依賴性而無法對其使用 * 先前的工作利用 full-system 模擬來克服,缺點是巨大的 overhead * FirmAFL 結合 full-system 模擬與 user-mode 來加速 * 本文認為目前 user-mode 的模擬並不完整 * 提出 EQUAFL,自動用 user-mode 模擬嵌入式應用程式 * 先用 system-mode 模擬,抓出會讓程式 crash 的關鍵,再將環境改至 user-mode * user-mode 可回放系統的網路行為 * 在 70 個網路應用程式下評估 EQUAFL,與最先進的其他 fuzz 工具比較 * 比 AFL-QEMU 快 26 倍、Firm-AFL 快 14 倍 * 發現 6 個 CVEs ## Introduction * 現今 IoT 開發注重功能而非安全,造成系統中存在漏洞 * Mirai * 灰盒 Fuzzing 常被用來測試程式,蒐集 PUT(program under test) 的回饋資訊 * 但因缺乏系統與硬體支援,無法直接用於嵌入式設備 * 利用模擬解決 * 模擬有 user-mode 與 full-system * 雖然前者 cost 低,但缺乏 system calls 與 execution context * 大多使用後者執行 * 先前的工作 Firm-AFL 利用切換 user-mode 與 full-system 加速 * 有 system call 跑 full-system * 沒 system call 跑 user-mode * 當 PUT 有一堆 system call 的時候,加速很少 * 希望完全在 user-mode 之下執行 * 提出 EQUAFL,利用強化的 user-mode 模擬跑灰盒 Fuzzing * Linux-based * 強化的 user-mode 指自動化設定執行環境,讓 system call 直接傳到 host 端 * EQUAFL 使用觀察重放策略 1. 在 full-system 模擬 PUT,觀察設定啟動變數、設定文件、設定網路等關鍵行為 2. 重放觀察到的行為去建立環境 * 動態產生設定文件和網路互動是最難的部分 * 在 70 個真實世界的 IoT Linux-based 應用程式評估 * 比 AFL-QEMU 的 full-system 模擬快 26 倍 * 比 Firm-AFL 快 14 倍 * 在 18 個設備上發現 10 個未知漏洞,包含 6 個 CVEs * 貢獻總結 * 提出 EQUAFL,自動建立執行 user-mode 環境來高效 fuzz * 基於 AFL 和 QEMU 實作 EQUAFL * 在 70 個應用程式下評估,發現 6 個 CVEs * [Open-Source](https://github.com/zyw-200/EQUAFL) ## Background ### Emulation-Based Fuzzing * QEMU 是常用的模擬器 * Full-system 模擬 kernel, drivers 和 應用程式 * User-mode 模擬將應用程式的 system calls 委託給 host * 快速、高效 * 缺乏兼容性,當 host 不支援該 system calls 就會失敗 * AFL 支援利用 QEMU 作為模擬引擎去對 PUT 做覆蓋率導向的灰盒 fuzz #### AFL + QEMU user-mode emulation * 預設之下,AFL 用 QEMU user-mode 模擬 * 直接將執行的 system calls 傳給 host * 可能會因 host 與 PUT 相容性問題而失敗 * ex: 執行 D-Link TRENDNet TEW-634GRU series 的 sbin/httpd,會因 "/var/run/httpd.pid: No such file or directory" 而失敗 * 常見失敗的原因 * 錯誤的啟動變數 * 因錯誤或是缺乏啟動變數而在開始就停止 * 缺乏動態產生的文件 * IoT 在開機過程常常會產生文件,缺乏這些文件會使 PUT 很早就停止 * 不一致的 NVRAM 設定 * IoT 設備中的 NVRAM 資料與 host 有衝突時會導致錯誤 * 不一致的網路行為 * 許多 PUT 需要透過網路與 user 互動,當 host 無法提供合適的網路時會就失敗 * 不一致的程式資源限制 * 某些情況下 host 的限制比韌體高得多,導致效率受限 * 缺乏硬體 * 某些情況下 PUT 需要特定的硬體來執行,缺乏硬體可能導致錯誤 * 總結來說,AFL + QEMU user-mode 會因為許多兼容性問題導致錯誤,可以透過 full-system 模擬來避免 #### AFL + QEMU full-system emulation * AFL 加上 full-system 模擬的 QEMU 能 fuzzing 整個 firmware image + application * 但整個 fuzzing 的速度會大幅下降 #### AFL + QEMU hybrid emulation * 為了解決上述問題,Firm-AFL 嘗試結合兩者 * 在 user-mode 下執行 code,並將 system calls 導向到 full-system 中 * 當程式頻繁地出現 system call 時,效率依舊低下 * Firm-AFL 仍然有進步空間 ### Terminology * Guest/Host Machine * 在 full-system 模擬中,guest 指包含韌體的虛擬機器、host 指跑著 OS 的那台實體機器 * host 用模擬器執行 guest * Page Global Directory * PGD 指程式執行時的 top physical page frame * 因為每個程式的 PGD 的開頭是唯一的,可用於識別 user-space 中的程式 ## Overview * 在 user-mode 下 fuzzing 很快但是容易失敗、在 full-system 下 fuzzing 容易成功但是缺乏效率 * 希望有 full-system 的成功率但越快越好 * 提出 EQUAFL(AFL-based Enhanced QEMU User-mode emulation) *  * 主要兩步驟 * observation * replay * observation 階段會用 full-system 模擬,紀錄 * launch variables * file generation * NVRAM related operation * network interaction * process resource limits * replay 階段利用蒐集到的資訊部屬設定在 host 上或是在 user-mode 重跑攔截到的 system-call * 調整 PUT 的 lifecycle 和 fuzzing 的 entry point,可從網路層做 fuzzing ## Approaches ### Launch Variables Settlement * 啟動變數是 PUT 在模擬系統中啟動的參數和環境變數 * PUT 表示為 $P^{*1}$、程式名、參數和環境變數表示為 $p^{name}$, $p^{vars}$ 和 $p^{envs}$ * 這些資訊會用很多種方式存在韌體中,例如配置文件、hard-encoded 在執行檔或是由父 process 傳遞,因此無法用靜態方式提取 * 直接用 full-system 模擬取得 #### Observation * 偵測 kernel function 的 do_execve 來得到程序的 pname pvars penvs * 三種 function call 會能計算這些地址 * 接著找到 QEMU 中最靠近這些指令的 Basic block * 最後在 full-system 模擬時存下這些 block 的值 #### Replay * 經過 Observation 後,我們得到一個集合的 pname pvars penvs(每個 process 就有一組) * 將 pname 設為想要測試的目標 process,並將 pvars penvs 設為對應的 pairs,進行 user-mode 模擬 ### Filesystem State Synchronization * 模擬時通常會掛載一個 filesystem,並在初始化時不斷改變它 * 沒有正確的 filesystem 導致 PUT 在 user-mode 執行錯誤 * observe-replay 觀察與文件相關的 system call,並在 host 執行 * 問題是在 host 上 replay 時可能會出現未知的值,例如下圖 *  * 提出 process-aware observation 的方法去 mapping 這些映射 #### Accurate Process Identification * guest 中需要做 process collection 和 process inference(收集和推斷) * 收集利用檢查 fork 和 execve 來檢測新的 process * 從 task_struct 得到 PGD, PID, PPID 等資訊 #### Process-aware Observation * 蒐集到 process 後,進一步蒐集他們的 system call * 過濾不影響文件的,剩餘的分為兩種 * 直接處理路徑,如 mkdir 等 * 處理 file desciptor(fd),如 open * 將 Process, fd_guest, fd_host 的關係建立起來後即可在 host 上重新執行 #### Replay *  * id_sys: 重放的 system call * p*: 目前的 process * obj_arg: id_sys 的主要參數(檔案路徑或是 fd) * other_args: id_sys 其他的參數 * RDIR: host 上韌體的 filesystem 的路徑 ### NVRAM Configuration * Firmadyne 中,使用一般文件紀錄 NVRAM 的配置 * 因為前面已經實現 filesysyem 的同步,所以 NVRAM 的配置也已經在 host 上存在 * 利用 LD_PRELOAD 使用自訂的 library 執行 PUT ### Network Behavior * 網路行為會受到外界互動的影響 * 為了模擬網路行為,觀察與網路有關的 system call 並建立狀態機 * 在 full-system 模擬中監控 socket,並利用 type 參數識別是否與網路有關 * 網路互動的狀態機模型如下 *  * 感覺 Fuzzing 的地方是 read/recv/recvfrom 那 ### Process Resource Limits * RLIMIT_NOFILE 是 PUT 可以打開的 fd 最大值 * 太大會降低 PUT 執行速度 * 通常 host 會超大,所以要重設 * 利用 Linux 中的 setrlimit 和 getrlimit system call 來取得這些值 ## Implementation ### Emulation #### Observation * 首先 EQUAFL 利用 FIRMADYNE 執行 PUT 和 full-system 模擬 * full-system 模擬用於紀錄所有 system call 執行的參數和 return 值 #### Replay * launch variables, filesystem state synchronization, NVRAM configuration 這三點,EQUAFL 直接在 host 上部屬一樣的資源 * launch variables 利用 IDA Pro 實現 * filesystem state synchronization 透過 Binwalk 解包韌體 * 利用 chroot 將提取的 filesystem 當作根目錄,相對路徑才不會錯誤 ### Fuzzing * 將接收網路輸入的 system call 當作入口點 * 輸入會進入到網路的內存區 * 檢測 read, recv, recvfrom 等等 ## Evaluation * 實現基於 QEMU 的 EQUAFL * 有對 full-system 和 user-mode 修改 * 修改 AFL 更改 afl-fuzz 接受的參數,正確加載目標的參數和環境變數 * 評估三點 * Compatibility 兼容性 * Efficiency 效率 * Vulnerability discovery 漏洞發現 ### Experiments Setup Benchmarks * 兩個數據集 * nbench 和 lmbench * 70 個來自 D-Link, TRENDnet, NETGEAR 的韌體 * 在 AFL-Full 和 Firm-AFL 都能成功模擬和測試 *  * 三個比較對象 * AFL-User * 預設的 AFL QEMU mode * AFL-Full * 將AFL 和 QEMU 的 full-system 模擬結合 * 利用 DECAF 中的 VMI 來監控目標 process * Firm-AFL * 交替切換 full-system 和 user-mode * AFL 有使用字典和種子 * 字典來自目標程式的靜態分析 * 種子是一個正常的網路請求 * 兼容性和效率評估的環境 * 12-core Intel(R) Xeon(R) E5-1650 v3 3.50GHz CPU * Ubuntu 18.04.5 LTS * 15.6GB RAM * 漏洞發現評估的環境 * 18-core Intel(R) Xeon(R) CPU E5-2699 v3 2.30GHz CPU * Ubuntu 18.04.5 LTS * 188GB RAM * 為了降低 Fuzz 的隨機性,每個實驗跑五次 ### Compatibility * AFL-Full 和 Firm-AFL 都可以成功 *  * CRA: 用初始的種子就 crash * HAN: 用初始的種子就 hang * ERR: 目標可以由 fuzzer 啟動,但有錯誤(例如找不到文件等) * SUCC: 成功 * EQUAFL 成功了 66 個,而 AFL-User 全失敗 *  * 與 full-system 的 system call 相似性,不同的部分大多是因為 process 通訊的差異造成 ### Efficiency * 兩種評估 * 與 AFL-Full 和 Firm-AFL 比較吞吐量 * EQUAFL 和 User-mode 比較 cost * 因為 User-mode 很多跑不起來,用第一個資料集來評估 * 吞吐量 * 收集 1188 個種子,計算平均執行時間(跑 5 次) * 平均執行時間的倒數為平均吞吐量 *  * 比 Full 快 26 倍、比 Firm 快 14 倍 * cost *  *  * 基本上沒有額外 cost ### Vulnerability Discovery *  * 找到 10 個漏洞 * 9 個使用 NULL 指標 * 1 個整數 overflow * 其中 6 個得到 CVE *  * 24 小時內 unique 漏洞數 * 最快發現漏洞 ## Threats to Validity * 外部設備目前只支援 NVRAM * 與其它 process 互動的部分可能會出錯 * 多個程式交互的漏洞無法發掘 ## Related Work * Static analysis * PIE * Firmalice * DTaint * Karonte * SaTC * Dynamic analysis * Avatar * Firmadyne * FirmAE * Fuzzing * IOTFUZZER * boofuzz * Firmcorn * FirmFuzz * EM-Fuzz ## Conclusion * 提出 EQUAFL,為 Linux-based 韌體的網路應用程式 Fuzzing 的框架 * 透過增強的 User-mode 避免 full-system 的 cost * 發現 10 個漏洞,包含 6 個 CVE --- * [EQUAFL 網頁](https://sites.google.com/view/equafl/home?authuser=0) ###### tags: `paper`
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.