4、固件获取方法:从芯片直接读取(SPI/JTAG/SWD)、从设备备份、从官网/更新包提取、从OTA抓包获取
固件获取是逆向工程的第一步,也是最关键的一步。没有合法的固件镜像,后续的静态分析、动态调试和漏洞挖掘都无从谈起。在实际工程中,固件的来源多种多样,不同来源对应不同的技术难度、设备约束和风险等级。本章系统梳理四条主流获取路径:芯片级直接读取(SPI/JTAG/SWD)、设备备份提取、官网/更新包解析、OTA流量抓取。每条路径都有其适用场景、前置条件和典型陷阱,掌握这些方法的核心原理与操作细节,是开展嵌入式安全研究的基础能力。
4.1 从芯片直接读取:SPI Flash编程器、JTAG与SWD
核心原理
芯片级读取是最底层的固件获取方式,直接操作物理存储介质或调试接口。SPI Flash是嵌入式设备中最常见的固件存储介质,NOR Flash通过SPI总线与主控芯片通信,固件以二进制形式线性存储。使用编程器(如CH341A、FT2232H、TL866II Plus)配合烧录座或飞线,即可绕过系统软件直接读取Flash内容。JTAG(IEEE 1149.1)和SWD(Serial Wire Debug)则是芯片调试接口,通过调试器(如J-Link、OpenOCD配合FTDI)访问CPU内核,进而读取片内Flash或外部存储。JTAG提供完整的边界扫描和调试能力,SWD是ARM Cortex-M系列的精简替代方案,仅需两根线(SWDIO和SWCLK)。
判断方法与操作流程
选择哪种芯片级读取方式,取决于目标设备的硬件设计和安全防护。首先拆解设备,观察PCB上是否存在SPI Flash芯片(常见封装为SOIC-8、SOIC-16、WSON-8),丝印通常以"25"开头(如Winbond W25Q128、MXIC MX25L25645G)。若Flash芯片可拆卸,优先使用编程器配合烧录座读取;若芯片焊接在板上,可考虑飞线或热风枪拆卸。对于MCU内置Flash,需确认是否开放调试接口——查看PCB上是否有4针(SWD)或10针/20针(JTAG)调试排针。操作流程如下:
- 识别存储介质:使用放大镜或显微镜观察芯片丝印,查阅数据手册确认容量、电压和指令集。
- 选择连接方式:优先使用烧录座(DIP-8适配器),其次飞线连接(注意线长不超过10cm,避免信号干扰)。
- 配置编程器软件:如FlashROM、AsProgrammer、flashrom,选择正确的芯片型号和读操作。
- 读取并校验:读取后计算MD5/SHA256,重复读取两次对比哈希值,确保数据完整性。
- JTAG/SWD连接:使用J-Link或ST-Link连接调试口,通过OpenOCD或J-Flash读取片内Flash。
案例拆解:从智能路由器提取完整固件
某品牌智能路由器无法通过Web界面备份固件,且官方固件包经过加密。拆机后发现主板上有一颗Winbond W25Q256JV(256Mbit SPI NOR Flash),丝印清晰。使用CH341A编程器配合SOP-8测试夹,在断电状态下夹住Flash芯片,运行AsProgrammer选择W25Q256JV,以3.3V电压读取全片数据,耗时约12分钟,得到32MB的二进制文件。重复读取两次,MD5一致。随后用binwalk扫描,成功识别出uImage内核、SquashFS文件系统和U-Boot引导程序。此案例中,关键成功因素是选择了正确的编程器电压(3.3V而非5V),避免损坏芯片;同时使用测试夹而非飞线,降低了短路风险。
常见误区与总结复盘
- 误区一:认为所有SPI Flash都能直接读取——部分新芯片支持SFDP(Serial Flash Discoverable Parameters),编程器软件需更新数据库。
- 误区二:忽略电压域——现代低功耗设备使用1.8V Flash,编程器需支持电压切换。
- 误区三:JTAG被禁用——多数量产芯片会烧断JTAG保险丝或设置调试锁定,需先尝试其他路径。
芯片级读取的复盘要点:先拍照记录PCB布局和芯片丝印,再动手操作;读取前确认编程器固件版本;读取后立即备份原始镜像,后续分析均在副本上进行。
4.2 从设备备份:利用系统接口导出固件
核心原理
设备备份是指通过目标设备自身运行的系统或引导程序,将存储介质中的固件数据导出。这通常需要获得设备的Shell访问权限(通过UART串口、Telnet、SSH或漏洞利用),或者利用Bootloader(如U-Boot)提供的命令接口。在Linux嵌入式设备中,Flash通常被划分为多个MTD分区(如u-boot、kernel、rootfs、art),通过dd命令或cat /dev/mtdX即可读取原始数据。此方法的优势在于无需拆机或额外硬件,且能获取设备运行时视角的完整分区布局。
操作流程与关键命令
# 查看MTD分区布局
cat /proc/mtd
# 输出示例:
# dev: size erasesize name
# mtd0: 00100000 00010000 "u-boot"
# mtd1: 00400000 00010000 "kernel"
# mtd2: 01b00000 00010000 "rootfs"
# mtd3: 00010000 00010000 "art"
# 备份单个分区
dd if=/dev/mtd0 of=/tmp/u-boot.bin bs=65536 count=16
# 备份整个Flash(若存在mtdblock设备)
cat /dev/mtdblock0 > /tmp/full_flash.bin
# 通过U-Boot命令行备份
# 在U-Boot提示符下执行:
# sf probe 0
# sf read 0x82000000 0x0 0x1000000
# tftp 0x82000000 firmware.bin
若设备运行的是RTOS(如FreeRTOS、ThreadX),则需通过调试串口或自定义固件漏洞获取内存转储。部分设备提供Web管理界面的"配置备份"功能,但通常只导出配置文件而非完整固件,需甄别。
案例拆解:通过UART Shell备份工业网关固件
某工业物联网网关使用OpenWrt系统,默认关闭SSH但开放UART调试串口。通过拆机连接UART(波特率115200,TX/RX/GND三线),在启动过程中中断进入U-Boot命令行。执行printenv查看启动参数,发现bootcmd中包含sf read命令,确认SPI Flash已初始化。随后执行sf probe 0识别Flash,使用sf read 0x82000000 0x0 0x2000000将32MB Flash读取到内存,再通过TFTP上传到本地服务器。整个过程无需登录系统,且绕过了OpenWrt的文件系统权限限制。此案例中,U-Boot的TFTP功能是导出固件的关键通道,前提是设备网络可达且TFTP服务器配置正确。
md5sum对比各分区哈希值,确保数据一致性。若设备有多个相同型号,可交叉对比备份结果。
常见误区与总结复盘
- 误区一:混淆配置备份与固件备份——配置导出文件(如.xml、.json)不包含可执行代码,无法用于逆向分析。
- 误区二:忽略分区偏移——直接读取
/dev/mtd0得到的是分区起始地址的数据,若需完整Flash镜像,需按偏移拼接各分区。 - 误区三:Bootloader命令不熟悉——U-Boot的
sf、mmc、nand命令族需提前查阅手册。
设备备份的复盘要点:优先尝试UART串口获取Shell,这是成本最低的入口;备份过程中保持设备供电稳定,避免断电导致分区表损坏;备份完成后立即恢复设备正常运行状态。
4.3 从官网/更新包提取:固件解包与格式识别
核心原理
厂商官网提供的固件升级包是最便捷的获取途径,但通常经过封装和压缩。固件包格式多样:可能是单个二进制文件(含头部信息)、ZIP/RAR压缩包、加密容器或专有格式(如TRX、BIN、IMG、PKG)。提取的核心在于识别文件格式并去除封装层。常用工具包括binwalk(自动扫描文件签名)、firmware-mod-kit(自动化解包)、jefferson(JFFS2镜像解析)、sasquatch(SquashFS变体解析)。对于加密固件,需分析加密算法(常见AES、XOR、自定义流密码),密钥可能硬编码在Bootloader或设备驱动中。
操作流程与工具链
# 使用binwalk扫描固件结构
binwalk firmware.bin
# 提取所有识别到的文件
binwalk -e firmware.bin
# 查看文件系统类型
binwalk -A firmware.bin
# 使用firmware-mod-kit解包
./extract-firmware.sh firmware.bin
# 手动分析头部信息
hexdump -C firmware.bin | head -50
关键步骤包括:文件签名识别(如U-Boot的"U-Boot"字符串、SquashFS的"hsqs"魔数、TRX头的"TRX"标识)、熵分析(高熵区域可能为加密数据或压缩数据)、偏移修正(部分固件在头部包含长度字段,需校验)。
案例拆解:解析某IP摄像头加密固件
某IP摄像头官网提供升级包IPC_Upgrade_20240601.bin,大小约8MB。binwalk扫描未识别出任何已知签名,文件头部为固定字节5A A5 00 01。使用hexdump查看头部,发现偏移0x10处存在长度字段0x007FFFFF,与文件大小吻合。进一步分析发现,从偏移0x200开始的数据熵值接近1.0,疑似加密。通过搜索固件中的字符串,在偏移0x1A0处发现明文"KEY=0x3C6B7A91",推测为XOR加密密钥。使用Python脚本对加密区域逐字节异或,成功还原出SquashFS文件系统,最终提取出完整的rootfs。此案例说明,加密固件的密钥往往以明文形式存储在固件头部或Bootloader中,需仔细搜索。
常见误区与总结复盘
- 误区一:依赖单一工具——binwalk并非万能,需结合hexdump和strings手动分析。
- 误区二:忽略固件头校验——部分固件包含CRC32或SHA256校验,修改后需重新计算。
- 误区三:加密算法误判——XOR加密简单但易破解,AES-CBC等需找到密钥和IV。
官网包提取的复盘要点:先做熵分析判断是否加密,再决定手动分析还是自动化工具;保存原始固件包,所有解包操作在副本上进行;记录解包过程中的偏移和算法参数,便于复现。
4.4 从OTA抓包获取:网络流量捕获与协议分析
核心原理
OTA(Over-The-Air)升级是物联网设备常见的固件更新方式。设备通过HTTP/HTTPS、MQTT、CoAP等协议从服务器下载固件。抓包获取的核心是在设备与服务器之间建立中间人代理,截获固件传输流量。对于HTTP明文流量,使用Wireshark或tcpdump即可直接捕获;对于HTTPS流量,需安装自定义CA证书到设备信任库,或通过SSL剥离(SSLStrip)降级。部分设备使用私有协议或加密隧道,需逆向分析协议格式。OTA抓包的难点在于:设备可能校验服务器证书、固件签名、时间戳等,需完整模拟服务器响应。
操作流程与工具配置
# 使用tcpdump在网关捕获流量
tcpdump -i eth0 -w ota_capture.pcap host 192.168.1.100
# 使用mitmproxy拦截HTTPS流量
mitmproxy --mode transparent -p 8080
# 配置设备代理(需在设备上设置)
# export http_proxy=http://192.168.1.50:8080
# export https_proxy=http://192.168.1.50:8080
# 分析PCAP中的固件传输
wireshark ota_capture.pcap
# 过滤HTTP请求:http.request.method == "GET" || http.request.method == "POST"
# 导出固件对象:File -> Export Objects -> HTTP
关键步骤包括:网络拓扑确认(设备连接方式、网关IP)、代理配置(透明代理或显式代理)、证书安装(生成CA证书并导入设备)、触发OTA升级(通过设备管理界面或发送特定指令)、流量过滤与重组(从PCAP中提取固件二进制)。
案例拆解:捕获智能门锁OTA固件
某智能门锁通过Wi-Fi连接手机App进行固件升级,使用HTTPS协议。在局域网内搭建mitmproxy透明代理,将门锁的网关流量指向代理服务器。生成自签名CA证书,通过门锁的调试接口(UART)将证书导入系统信任库。触发App升级操作,mitmproxy捕获到对https://firmware.iotvendor.com/v1/update的POST请求,响应体为加密的固件包。通过分析请求头中的X-Device-ID和X-Signature字段,发现签名基于设备MAC地址和固件版本号生成。使用门锁的Bootloader中提取的AES密钥解密响应体,成功还原固件。此案例中,证书导入和签名算法逆向是两大难点,耗时约3小时。
常见误区与总结复盘
- 误区一:忽略TLS证书固定——部分App使用证书固定(Certificate Pinning),需通过Frida或Xposed绕过。
- 误区二:固件分包传输——OTA固件可能被切分为多个分片,需按序重组并处理分片头。
- 误区三:代理配置遗漏——设备可能绕过系统代理,需使用iptables强制重定向流量。
OTA抓包的复盘要点:先确认协议类型(HTTP/HTTPS/私有),再决定代理方案;证书导入需谨慎,避免破坏设备信任链;捕获后立即计算固件哈希,与后续分析结果比对。
4.5 四条路径的对比与选择策略
| 获取路径 | 技术难度 | 硬件需求 | 数据完整性 | 适用场景 | 主要风险 |
|---|---|---|---|---|---|
| SPI Flash编程器 | ★★☆ | 编程器、测试夹/飞线 | 高(全片读取) | Flash可拆卸、无读保护 | 电压错误损坏芯片 |
| JTAG/SWD调试 | ★★★ | J-Link/ST-Link、调试线 | 高(片内Flash) | MCU开放调试接口 | 引脚接反烧毁设备 |
| 设备备份 | ★★☆ | UART转USB模块 | 中(依赖分区映射) | 有Shell或Bootloader | 分区表损坏 |
| 官网/更新包 | ★☆☆ | 无(纯软件) | 中(可能加密/裁剪) | 厂商提供升级包 | 加密算法复杂 |
| OTA抓包 | ★★★★ | 代理服务器、抓包工具 | 中(依赖协议分析) | 设备支持远程升级 | 法律合规风险 |
选择策略上,建议遵循"由易到难、由软到硬"的原则:首先尝试官网下载和更新包解析,这是零成本且无风险的方式;若固件加密或缺失,再尝试设备备份(通过UART或漏洞获取Shell);若设备封闭且无调试接口,最后考虑芯片级读取。OTA抓包通常作为补充手段,用于获取最新版本固件或验证升级机制。在实际项目中,多条路径往往组合使用——例如通过官网包获取旧版本固件,通过OTA抓包获取新版本,通过芯片读取获取Bootloader和校准数据,最终拼凑出完整的固件分析素材。