
Firmware Analysis
- 22 installs
- 1.6k repo stars
- Updated July 19, 2026
- wgpsec/aboutsecurity
Helps with ai & agent building tasks during AI-assisted development.
About
firmware-analysis is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- firmware-analysis
- AI & Agent Building
- AI-coding skill
Firmware Analysis by the numbers
- 22 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #10,137 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wgpsec/aboutsecurity --skill firmware-analysisAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 22 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | July 19, 2026 |
| Repository | wgpsec/aboutsecurity ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
固件安全分析方法论
核心流程:获取固件 → 解包提取文件系统 → 静态分析敏感信息 → 动态模拟运行 → 漏洞挖掘 → 固件修改重打包
深入参考
- 固件分析完整技术细节与工具参考 → references/firmware-analysis-techniques.md
---
Phase 1: 固件获取
固件获取途径决策树:
├─ 厂商官网下载(支持页/FTP/CDN)
│ └─ Google dork: site:vendor.com filetype:bin OR filetype:img "firmware"
├─ 云存储扫描
│ └─ S3Scanner / GrayhatWarfare 搜索厂商名+firmware
├─ 设备直接提取
│ ├─ UART 串口连接
│ │ ├─ 识别 TX/RX/GND 引脚(万用表/逻辑分析仪)
│ │ └─ picocom -b 115200 /dev/ttyUSB0
│ ├─ JTAG/SWD 调试接口
│ │ └─ OpenOCD 连接读取 flash
│ ├─ SPI Flash 芯片直读
│ │ └─ SOIC-8 夹具 + flashrom
│ └─ eMMC 直读(ISP 焊点)
├─ 中间人截获更新包
│ └─ 设置代理拦截 OTA 更新请求
├─ 移动应用提取
│ └─ apktool d vendor-app.apk → assets/firmware/
└─ 从 bootloader dump
└─ U-Boot: md.b / nand read / sf read从 SPI Flash 直接读取
# 使用 CH341A 编程器 + SOIC-8 夹具
flashrom -p ch341a_spi -r flash.bin
# 验证读取一致性(读两次比较)
flashrom -p ch341a_spi -r flash2.bin
md5sum flash.bin flash2.bin通过 UART 获取 Shell
# 连接 UART(常见波特率: 115200, 9600, 57600)
picocom -b 115200 /dev/ttyUSB0
# 如果 UART 只有日志输出(RX 被忽略),编辑 U-Boot env 强制 shell
# 1. dump flash → 2. 修改 bootargs 加入 init=/bin/sh → 3. 重算 CRC32 → 4. 回写从移动应用提取固件
apktool d vendor-app.apk -o vendor-app
ls vendor-app/assets/firmware/
# 常见路径: assets/fw/, res/raw/, assets/firmware/Phase 2: 解包与文件系统提取
固件解包决策树:
├─ binwalk 自动提取(首选)
│ └─ binwalk -ev firmware.bin
├─ binwalk 识别但提取失败
│ ├─ 手动 dd 切割 + 对应工具解压
│ │ ├─ squashfs → unsquashfs
│ │ ├─ jffs2 → jefferson
│ │ ├─ cramfs → cramfsck
│ │ ├─ cpio → cpio -ivd
│ │ ├─ ubifs → ubireader_extract_images
│ │ └─ yaffs2 → unyaffs
│ └─ firmware-mod-kit 辅助
├─ 固件加密
│ ├─ 检查熵值: binwalk -E firmware.bin
│ │ ├─ 高熵 → 可能加密或压缩
│ │ └─ 低熵 → 未加密
│ ├─ 寻找解密密钥(bootloader/旧版本固件/逆向加密逻辑)
│ └─ 某些厂商用 AES-CBC + 硬编码 key/IV
└─ 完全未知格式 → hexdump 分析 magic bytesbinwalk 标准流程
# 初步分析(不提取,仅识别)
binwalk firmware.bin
# 熵分析判断是否加密
binwalk -E firmware.bin
# 自动递归提取
binwalk -ev firmware.bin
# 提取结果通常在 _firmware.bin.extracted/ 目录
ls _firmware.bin.extracted/手动文件系统提取
# 查找文件系统偏移
binwalk firmware.bin | grep -i "squashfs\|jffs2\|cramfs\|ubifs"
# 用 dd 切割(示例: squashfs 在偏移 0x1A0094)
dd if=firmware.bin bs=1 skip=$((0x1A0094)) of=rootfs.squashfs
# 解压 squashfs
unsquashfs rootfs.squashfs
ls squashfs-root/
# 解压 jffs2
jefferson rootfs.jffs2 -d jffs2-root
# 解压 cpio
cpio -ivd --no-absolute-filenames -F rootfs.cpio
# 解压 ubifs
ubireader_extract_images -u UBI -s <start_offset> firmware.bin基础文件信息收集
file firmware.bin
strings -n8 firmware.bin
strings -tx firmware.bin | head -50
hexdump -C -n 512 firmware.bin
fdisk -lu firmware.binPhase 3: 静态分析
静态分析重点目标:
├─ 硬编码凭据
│ ├─ /etc/shadow, /etc/passwd
│ ├─ grep -r "password\|passwd\|secret\|key" etc/
│ └─ 配置文件中的默认账户密码
├─ 加密材料
│ ├─ SSL 证书与私钥: etc/ssl/, *.pem, *.key
│ ├─ SSH 密钥: etc/ssh/ssh_host_*
│ └─ API 密钥 / Token
├─ 后门与调试接口
│ ├─ telnetd / dropbear 配置
│ ├─ 隐藏的 CGI 端点
│ └─ 调试用 web shell
├─ 网络服务配置
│ ├─ Web 服务器配置(lighttpd/uhttpd/mini_httpd)
│ ├─ MQTT 凭据与 broker 地址
│ └─ 云平台 API endpoint
├─ 启动脚本分析
│ ├─ /etc/init.d/, /etc/rc.d/
│ └─ 服务启动顺序与权限
└─ 二进制安全检查
└─ checksec --file=<binary>凭据与敏感信息搜索
# 进入提取的文件系统
cd squashfs-root/
# 检查用户凭据
cat etc/shadow 2>/dev/null
cat etc/passwd
# 搜索硬编码密码
grep -rn "password\|passwd\|secret\|api_key\|token" etc/ --include="*.conf" --include="*.cfg"
grep -rn "password\|passwd" usr/lib/ --include="*.lua" --include="*.sh"
# 搜索 SSL/SSH 密钥
find . -name "*.pem" -o -name "*.key" -o -name "*.crt" -o -name "ssh_host_*"
# 搜索 URL 和 IP 地址
grep -rn "http://\|https://\|ftp://" . --include="*.conf" --include="*.sh" --include="*.lua"
grep -rEn "\b[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\b" etc/
# 搜索 base64 编码内容(可能隐藏凭据)
grep -rn "^[A-Za-z0-9+/=]\{20,\}$" etc/自动化分析工具
# Firmwalker - 自动搜索敏感信息
./firmwalker.sh squashfs-root/
# EMBA - 综合固件安全分析
sudo ./emba -f firmware.bin -l ./logs
# LinPEAS(在模拟环境中运行)
# 拷贝到模拟的文件系统中执行二进制保护检查
# 检查所有 ELF 二进制的安全编译选项
find squashfs-root/ -executable -type f -exec file {} \; | grep ELF
checksec --file=squashfs-root/usr/bin/httpd
checksec --file=squashfs-root/usr/sbin/dropbear云凭据与 MQTT 配置提取
# 搜索 MQTT 配置
grep -rn "mqtt\|broker\|mosquitto" etc/ usr/ --include="*.conf" --include="*.json"
# 搜索云端点 URL 与 token 派生逻辑
grep -rn "/pf/\|deviceId\|STATIC_KEY" usr/bin/ usr/lib/
strings usr/bin/cloud_agent | grep -i "mqtt\|api\|token\|key\|secret"Phase 4: 动态分析(QEMU 模拟)
动态分析决策树:
├─ 单个二进制模拟
│ ├─ 确认架构: file <binary>
│ ├─ MIPS big-endian → qemu-mips
│ ├─ MIPS little-endian → qemu-mipsel
│ ├─ ARM → qemu-arm
│ ├─ ARM64 → qemu-aarch64
│ └─ 需要 chroot 或 --root 指向文件系统
├─ 全系统模拟
│ ├─ Firmadyne(自动化,推荐)
│ ├─ Firmware Analysis Toolkit(基于 Firmadyne)
│ └─ 手动 QEMU system 模拟
└─ 真实设备动态调试
├─ gdbserver 远程调试
└─ Frida hook单个二进制模拟
# 安装 QEMU 用户态模拟器
sudo apt-get install qemu-user-static
# 确认目标架构
file squashfs-root/bin/busybox
# MIPS 模拟(以提取的文件系统为根)
sudo chroot squashfs-root /usr/bin/qemu-mips-static /bin/busybox ls
# ARM 模拟
sudo chroot squashfs-root /usr/bin/qemu-arm-static /usr/sbin/httpd
# 带 strace 的模拟(观察系统调用)
qemu-mips-static -strace ./squashfs-root/usr/bin/target_binary全系统模拟(Firmadyne)
# Firmadyne 流程
# 1. 提取固件文件系统
python3 ./sources/extractor/extractor.py -b <brand> -sql <psql_ip> -np -nk firmware.bin images/
# 2. 识别架构
python3 ./scripts/getArch.sh images/<image_id>.tar.gz
# 3. 创建 QEMU 镜像
python3 ./scripts/makeImage.sh <image_id>
# 4. 推断网络配置
python3 ./scripts/inferNetwork.sh <image_id>
# 5. 启动模拟
python3 ./scratch/<image_id>/run.sh远程调试
# 在设备/模拟环境中启动 gdbserver
gdbserver :1234 /usr/bin/target_daemon
# 在主机上连接
gdb-multiarch /path/to/target_daemon
# (gdb) target remote <device-ip>:1234
# (gdb) set architecture mips
# (gdb) continuePhase 5: 漏洞挖掘
常见固件漏洞类型:
├─ 命令注入
│ ├─ Web CGI 参数未过滤
│ ├─ 系统调用拼接用户输入
│ └─ grep -rn "system\|popen\|exec\|eval" --include="*.c" --include="*.lua"
├─ 缓冲区溢出
│ ├─ strcpy/sprintf/gets 等不安全函数
│ ├─ 嵌入式系统通常缺少保护(no ASLR/NX/Canary)
│ └─ checksec 确认保护状态
├─ 认证绕过
│ ├─ 硬编码凭据
│ ├─ 后门账户
│ └─ session 管理缺陷
├─ 信息泄露
│ ├─ 未授权 API 端点
│ ├─ 调试信息暴露
│ └─ 配置文件可访问
├─ 降级攻击
│ ├─ 无版本号校验的签名更新机制
│ ├─ 旧版签名固件仍可刷入
│ └─ 绕过安全补丁
├─ MQTT/云凭据泄露
│ ├─ 硬编码 STATIC_KEY 派生 token
│ ├─ 明文 MQTT 凭据
│ └─ 弱 topic ACL 允许跨设备访问
└─ uClibc 堆利用(嵌入式 Linux 特有)
├─ fastbin 合并时的 fake chunk
├─ non-PIE 下 .data/.bss 地址稳定
└─ /proc/self/mem 写入 shellcodeWeb 服务漏洞测试
# 识别 Web 服务
nmap -sV -p 80,443,8080,8443 <device-ip>
# 抓取所有 CGI 端点
curl -s http://<device-ip>/ | grep -oP 'action="[^"]*"|href="[^"]*"'
find squashfs-root/www/ -name "*.cgi" -o -name "*.asp" -o -name "*.lua"
# 命令注入测试(静态分析后定向测试)
# 分析 CGI 二进制中 system() 调用的参数来源
strings squashfs-root/usr/bin/httpd | grep "system\|popen\|/bin/sh"更新机制审计
# 检查更新逻辑:是否验证版本号?
strings squashfs-root/usr/bin/upgrade_manager | grep -i "version\|rollback\|verify\|sign"
# 是否存在反降级计数器?
grep -rn "anti.rollback\|version.check\|monotonic" squashfs-root/etc/ squashfs-root/usr/Phase 6: 固件修改与重打包
固件修改流程:
├─ 修改文件系统内容
│ ├─ 添加 SSH 公钥到 /root/.ssh/authorized_keys
│ ├─ 修改 /etc/shadow(添加已知密码的用户)
│ ├─ 植入 reverse shell 或 busybox
│ └─ 修改启动脚本添加持久化后门
├─ 重打包文件系统
│ ├─ squashfs: mksquashfs <dir> rootfs.squashfs -comp xz
│ ├─ jffs2: mkfs.jffs2 -d <dir> -o rootfs.jffs2
│ └─ cramfs: mkcramfs <dir> rootfs.cramfs
├─ 重组固件镜像
│ ├─ dd 拼接各分区
│ ├─ firmware-mod-kit 自动重打包
│ └─ 更新 CRC/校验和(如果有)
└─ 刷入设备
├─ Web UI 上传
├─ TFTP/串口刷入
└─ flashrom 直接写入 SPI重打包示例
# 修改文件系统后重打包 squashfs
# 注意匹配原始压缩算法和块大小
mksquashfs squashfs-root/ new_rootfs.squashfs -comp xz -b 131072
# 用 firmware-mod-kit 重打包
./build-firmware.sh <extraction_dir>
# 手动拼接固件
dd if=header.bin of=modified_firmware.bin bs=1
dd if=new_rootfs.squashfs of=modified_firmware.bin bs=1 seek=<offset> conv=notrunc
# 重算 CRC(如果固件头包含校验和)
# 需要逆向分析固件头格式确定 CRC 算法和位置工具速查
| 工具 | 用途 |
|---|---|
| binwalk | 固件识别与提取 |
| firmware-mod-kit | 解包/重打包 |
| flashrom | SPI Flash 读写 |
| OpenOCD | JTAG 调试 |
| QEMU | 二进制/系统模拟 |
| Firmadyne | 自动化全系统模拟 |
| Ghidra / radare2 | 二进制逆向分析 |
| gdbserver + gdb-multiarch | 远程调试 |
| checksec | 二进制保护检查 |
| EMBA | 综合固件安全分析 |
| Firmwalker | 敏感信息搜索 |
| picocom / minicom | 串口通信 |
练习靶场
| 项目 | 说明 |
|---|---|
| OWASP IoTGoat | IoT 固件漏洞练习 |
| DVRF | Damn Vulnerable Router Firmware |
| DVAR | Damn Vulnerable ARM Router |
| ARM-X | ARM 固件模拟框架 |
| DVID | Damn Vulnerable IoT Device |
固件分析技术详细参考
固件基础概念
固件是存储在设备永久存储器中的基础软件,管理硬件组件与用户交互软件之间的通信。设备上电后首先加载固件,随后启动操作系统。对固件的审查和修改是识别安全漏洞的关键步骤。
信息收集(OSINT 阶段)
分析前需收集的设备信息:
- CPU 架构与运行的操作系统
- Bootloader 详细信息
- 硬件布局与数据手册(datasheet)
- 代码库规模与源码位置
- 外部库及许可证类型
- 更新历史与监管认证
- 架构图与流程图
- 已有安全评估与已知漏洞
可用的 OSINT 与静态分析工具:
- Coverity Scan (https://scan.coverity.com) - 免费静态分析
- Semmle LGTM - 代码质量分析
固件获取方法详解
常规获取途径
| 途径 | 说明 |
|---|---|
| 厂商直接提供 | 联系开发者/制造商获取 |
| 根据说明编译 | 从源码构建 |
| 官方支持站下载 | 厂商支持页面 |
| Google dork | site:vendor.com filetype:bin "firmware" "update" |
| 云存储扫描 | S3Scanner 扫描公开 bucket |
| 中间人截获 | 拦截 OTA 更新流量 |
| 设备硬件提取 | UART/JTAG/SPI/PICit |
| 网络嗅探 | 监听设备更新请求 |
| 硬编码端点 | 固件中的更新 URL |
| Bootloader dump | U-Boot shell 命令 |
| 芯片拆焊直读 | 最后手段,需要专业设备 |
UART 只读日志时强制获取 Shell
当 UART 的 RX 被忽略(只有日志输出)时,可通过离线编辑 U-Boot 环境变量获取 shell:
# 1. 使用 SOIC-8 夹具 + 编程器读取 SPI Flash(3.3V)
flashrom -p ch341a_spi -r flash.bin
# 2. 定位 U-Boot env 分区
# 编辑 bootargs 加入 init=/bin/sh
# 重新计算 U-Boot env 的 CRC32
# 3. 仅回写 env 分区并重启
# shell 应出现在 UART 输出上从移动应用提取固件
许多厂商将完整固件镜像打包在手机伴侣应用中,用于蓝牙/WiFi OTA 更新:
apktool d vendor-app.apk -o vendor-app
ls vendor-app/assets/firmware/
# 常见路径: assets/fw/, res/raw/, assets/firmware/文件系统提取详解
binwalk 自动提取
binwalk -ev firmware.bin
# 结果目录以文件系统类型命名:
# squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs手动提取(binwalk 签名不匹配时)
当 binwalk 无法自动识别文件系统 magic bytes 时,需要手动操作:
# 查找文件系统偏移
binwalk DIR850L_REVB.bin
# 输出示例:
# 1704084 0x1A0094 Squashfs filesystem, little endian, version 4.0, compression:lzma
# dd 切割文件系统
dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
# 或使用十六进制偏移
dd if=DIR850L_REVB.bin bs=1 skip=$((0x1A0094)) of=dir.squashfs各文件系统类型解压命令
| 文件系统 | 解压命令 |
|---|---|
| squashfs | unsquashfs dir.squashfs |
| cpio | cpio -ivd --no-absolute-filenames -F <bin> |
| jffs2 | jefferson rootfsfile.jffs2 |
| ubifs (NAND) | ubireader_extract_images -u UBI -s <offset> <bin> |
| yaffs2 | unyaffs image.yaffs2 |
| cramfs | cramfsck -x <output_dir> image.cramfs |
文件系统安全分析
关键检查位置
| 路径/项目 | 检查内容 |
|---|---|
| etc/shadow, etc/passwd | 用户凭据、默认密码 |
| etc/ssl/ | SSL 证书和私钥 |
| etc/ssh/ | SSH host 密钥 |
| etc/init.d/, etc/rc.d/ | 启动脚本、服务配置 |
| 配置文件 (.conf, .cfg) | 硬编码凭据、API 端点 |
| Web 目录 | CGI 脚本、管理界面 |
| 二进制文件 | 不安全函数、后门 |
自动化分析工具
| 工具 | 说明 |
|---|---|
| LinPEAS | 权限提升路径与敏感信息搜索 |
| Firmwalker | 固件敏感信息自动搜索 |
| FACT | Firmware Analysis and Comparison Tool,综合分析 |
| FwAnalyzer | 固件安全策略检查 |
| ByteSweep | 自动化固件安全扫描 |
| EMBA | 嵌入式固件静态/动态分析框架 |
编译二进制安全检查
使用 checksec.sh 检查 Unix 二进制保护状态(NX/ASLR/Canary/PIE/RELRO)。嵌入式系统的二进制通常缺少这些保护,使其更容易被利用。
云配置与 MQTT 凭据提取
基于 token 派生的云端点
许多 IoT 设备使用可预测的 URL 格式从云端获取配置:
https://<api-host>/pf/<deviceId>/<token>其中 token 由设备本地计算,例如:token = MD5(deviceId || STATIC_KEY) 的大写十六进制表示。
提取流程
# 1. 从 UART 日志获取 deviceId
picocom -b 115200 /dev/ttyUSB0
# 寻找类似: Online Config URL https://api.vendor.tld/pf/<deviceId>/<token>
# 2. 从固件逆向恢复 STATIC_KEY 和算法
# Ghidra/radare2 搜索 "/pf/" 路径或 MD5 调用
# 3. 派生 token
DEVICE_ID="d88b00112233"
STATIC_KEY="cf50deadbeefcafebabe"
printf "%s" "${DEVICE_ID}${STATIC_KEY}" | md5sum | awk '{print toupper($1)}'
# 4. 获取云配置(含 MQTT 凭据)
API_HOST="https://api.vendor.tld"
TOKEN=$(printf "%s" "${DEVICE_ID}${STATIC_KEY}" | md5sum | awk '{print toupper($1)}')
curl -sS "$API_HOST/pf/${DEVICE_ID}/${TOKEN}" | jq .
# 常见字段: mqtt host/port, clientId, username, password, topic prefix
# 5. 使用 MQTT 凭据(在授权范围内)
mosquitto_sub -h <broker> -p <port> -V mqttv311 \
-i <client_id> -u <username> -P <password> \
-t "<topic_prefix>/<deviceId>/admin" -vQEMU 模拟详解
架构识别与工具安装
# 安装 QEMU 全套
sudo apt-get install qemu qemu-user qemu-user-static \
qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utils
# 确认二进制架构
file ./squashfs-root/bin/busybox
# 输出示例: ELF 32-bit MSB executable, MIPS, MIPS32 version 1架构对应的 QEMU 命令
| 架构 | 用户态模拟器 | 系统模拟器 |
|---|---|---|
| MIPS big-endian | qemu-mips | qemu-system-mips |
| MIPS little-endian | qemu-mipsel | qemu-system-mipsel |
| ARM | qemu-arm | qemu-system-arm |
| ARM64 | qemu-aarch64 | qemu-system-aarch64 |
全系统模拟工具
| 工具 | 说明 |
|---|---|
| Firmadyne | 自动化固件模拟,支持网络配置推断 |
| Firmware Analysis Toolkit | 基于 Firmadyne 的封装,简化流程 |
| ARM-X | ARM 固件模拟与漏洞研究框架 |
运行时分析技术
远程 GDB 调试
# 在目标设备上(拷贝静态链接的 gdbserver)
gdbserver :1234 /usr/bin/targetd
# 在主机上
gdb-multiarch /path/to/targetd
# (gdb) target remote <device-ip>:1234常用运行时分析工具
- gdb-multiarch: 跨架构调试
- Frida: 动态插桩,hook 函数调用
- Ghidra: 设置断点、反编译分析
- strace/ltrace: 系统调用/库函数调用追踪
- fuzzing: 对暴露的服务进行模糊测试
固件降级攻击
攻击条件
当更新机制仅验证签名但不检查版本号或单调递增计数器时,攻击者可以刷入旧的(已签名的)含漏洞固件。
攻击流程
1. 获取旧版签名固件(厂商下载页/CDN/APK 内置/第三方存档) 2. 通过暴露的更新通道上传(Web UI/移动应用 API/USB/TFTP/MQTT) 3. 利用旧版本中已修补的漏洞(如命令注入) 4. 获取持久化后刷回新版或禁用更新
更新逻辑审计清单
- 更新端点的传输/认证是否充分保护?
- 设备是否在刷入前比较版本号或反降级计数器?
- 签名验证是否在安全启动链中完成?
- 用户态代码是否进行额外验证(分区表/型号检查)?
- 备份/恢复更新流程是否复用相同验证逻辑?
uClibc 嵌入式堆利用
嵌入式 Linux 常用 uClibc 代替 glibc,其堆管理有特殊特性:
- Fastbins + 合并:uClibc 使用类似 glibc 的 fastbins,大分配触发
__malloc_consolidate(),fake chunk 需通过检查(合理 size, fd=0, 周围 chunk 标记为 in-use) - Non-PIE + ASLR:主程序非 PIE 时
.data/.bss地址固定,可将 fastbin 分配到函数指针表 - NUL 字节截断:JSON 解析中
\x00可停止解析但保留后续攻击载荷 - /proc/self/mem 写入 shellcode:ROP 链调用
open("/proc/self/mem")+lseek()+write()植入 shellcode
专用分析环境
| 操作系统 | 说明 |
|---|---|
| AttifyOS | IoT 安全评估专用发行版,预装分析工具 |
| EmbedOS | 基于 Ubuntu 18.04 的嵌入式安全测试系统 |
参考资源
- Firmware Security Testing Methodology: https://scriptingxss.gitbook.io/firmware-security-testing-methodology/
- Practical IoT Hacking: The Definitive Guide to Attacking the Internet of Things (书籍)
- OWASP IoTGoat: https://github.com/OWASP/IoTGoat
- DVRF: https://github.com/praetorian-code/DVRF
- ARM-X: https://github.com/therealsaumil/armx