4、固件获取与提取:从官网、设备Flash、OTA包、U-Boot等途径获取固件,使用Binwalk、dd、flashrom等工具提取文件系统
固件是IoT设备渗透测试的起点,也是决定测试深度与效率的核心资产。没有固件,测试者只能依赖黑盒手段,面对未知协议与加密流量时往往寸步难行;而一旦拿到固件并成功提取文件系统,就可以开展静态代码审计、后门查找、硬编码凭据挖掘、漏洞模式识别等白盒分析。本章围绕固件的获取途径与提取方法展开,覆盖官网下载、Flash芯片读取、OTA包捕获、U-Boot交互等主流渠道,并结合Binwalk、dd、flashrom等工具给出可落地的操作流程。固件获取与提取并非简单的“下载+解包”,而是涉及硬件接口识别、存储介质选型、文件系统格式判断、数据完整性校验等多个环节的系统工程。以下内容将按照“获取途径→提取工具→实战案例→常见误区”的逻辑线,帮助学员建立完整的固件采集与还原能力。
4.1 固件获取的四大途径与适用场景
4.1.1 官网与厂商支持渠道
官网下载是最直接、最合规的固件获取方式。多数IoT设备厂商会在支持页面提供固件更新包,用于修复漏洞或添加功能。测试者应优先从官网获取固件,因为其版本明确、来源可信,且通常附带版本说明与哈希校验值。实际操作中,需要关注以下细节:
- 固件格式识别:官网固件可能是
.bin、.img、.trx、.pkg、.zip等格式,需先通过file命令判断文件类型。 - 版本选择策略:建议同时下载多个历史版本,便于对比分析漏洞修复差异,也便于在旧版本中挖掘未修复的漏洞。
- 签名与哈希校验:部分厂商会提供MD5/SHA256值,下载后应校验完整性,避免下载到损坏或被篡改的文件。
4.1.2 设备Flash芯片直接读取
当官网固件不可得或需要获取设备当前运行的确切固件时,直接从硬件Flash芯片读取是最可靠的方式。IoT设备常用的存储介质包括SPI NOR Flash、SPI NAND Flash、并行NOR、eMMC等。读取Flash需要以下硬件准备:
- 识别Flash芯片型号:拆开设备外壳,找到板载Flash芯片,记录型号(如Winbond W25Q128、Macronix MX25L25645G等)。
- 选择编程器或读取工具:常用方案包括CH341A编程器、RT809H、树莓派+flashrom软件等。
- 连接与读取:使用测试夹或焊接飞线连接芯片引脚,通过编程器软件或flashrom命令读取完整Flash内容。
对于SPI NOR Flash,flashrom是Linux下最常用的工具,支持大量芯片型号。读取命令示例:
# 安装flashrom
sudo apt install flashrom
# 检测芯片
sudo flashrom -p ch341a_spi
# 读取完整Flash内容到文件
sudo flashrom -p ch341a_spi -r flash_dump.bin
# 验证读取结果
sha256sum flash_dump.bin
4.1.3 OTA升级包捕获与分析
OTA(Over-The-Air)升级是IoT设备固件更新的主要方式。测试者可以通过以下途径获取OTA包:
- 网络抓包:在设备与升级服务器之间部署代理(如Burp Suite、mitmproxy),捕获HTTPS流量并尝试解密(需安装CA证书)。
- 固件服务器分析:通过分析设备固件中的升级配置(如
/etc/ota.conf),找到升级服务器URL,直接下载固件包。 - 本地缓存提取:部分设备会将OTA包缓存在
/tmp或/data分区,可通过Shell访问直接拷贝。
OTA包可能是全量包或差分包。全量包包含完整固件,可直接提取;差分包仅包含变更部分,需要结合旧版本固件进行还原,难度较大。部分厂商会对OTA包进行加密或签名,此时需要逆向分析解密算法或提取设备中的密钥。
4.1.4 U-Boot引导器交互获取
U-Boot是嵌入式Linux设备常用的引导加载程序。如果设备留有串口调试接口(UART),测试者可以在上电时通过串口进入U-Boot命令行,利用其内置命令获取固件。常用方法包括:
- 内存转储:在U-Boot中,使用
md命令读取内存内容,将固件从内存导出。 - TFTP下载:如果U-Boot支持网络功能,可通过
tftp命令将Flash中的固件上传到本地TFTP服务器。 - NAND/NOR操作:使用
nand read或sf read命令读取Flash分区内容。
U-Boot方式的关键在于能够进入命令行。通常需要按住设备上的复位键或在上电瞬间发送特定字符(如连续发送Ctrl+C)中断自动启动流程。
| 获取途径 | 适用场景 | 优势 | 局限性 |
|---|---|---|---|
| 官网下载 | 厂商公开固件、版本对比 | 合规、便捷、版本明确 | 可能缺少最新版或定制版 |
| Flash芯片读取 | 设备当前固件、无官网资源 | 最真实、完整 | 需要硬件拆解、可能损坏设备 |
| OTA包捕获 | 设备已联网、升级频繁 | 可获得最新固件 | 可能加密、差分包还原困难 |
| U-Boot交互 | 有串口调试接口 | 无需拆Flash、可选择性读取 | 需要串口硬件、可能被禁用 |
4.2 固件提取工具链:Binwalk、dd与flashrom
4.2.1 Binwalk:固件分析的核心工具
Binwalk是固件分析领域最常用的开源工具,能够扫描固件镜像中的嵌入式文件、压缩数据、文件系统签名等。其核心功能包括:
- 签名扫描:识别固件中嵌入的文件类型(如gzip、lzma、squashfs、jffs2、ubifs等)。
- 自动提取:使用
-e参数自动提取识别到的文件系统与压缩包。 - 递归提取:
-M参数配合-e可递归提取嵌套的压缩包。 - 熵分析:
-E参数显示固件的熵值分布,帮助识别加密区域或压缩区域。
Binwalk的基本使用流程如下:
# 扫描固件中的文件签名
binwalk firmware.bin
# 自动提取所有识别到的文件
binwalk -e firmware.bin
# 递归提取(处理嵌套压缩)
binwalk -Me firmware.bin
# 查看熵值分布,识别加密区域
binwalk -E firmware.bin
对于提取出的squashfs文件系统,可以使用unsquashfs工具进一步解包:
# 解包squashfs文件系统
unsquashfs squashfs-root.img
4.2.2 dd:精确切割与分区提取
dd是Linux下的经典数据复制工具,在固件提取中主要用于从完整Flash镜像中按偏移量切割出特定分区。当Binwalk无法自动识别分区边界时,dd可以手动指定偏移和大小进行提取。常见用法:
# 从Flash镜像中提取从0x100000开始、大小为0x800000的分区
dd if=flash_dump.bin of=kernel.bin bs=1 skip=$((0x100000)) count=$((0x800000))
# 提取文件系统分区(假设从0x900000开始)
dd if=flash_dump.bin of=rootfs.img bs=1 skip=$((0x900000)) count=$((0x700000))
使用dd的关键在于准确确定分区的偏移量和大小。可以通过以下方式获取分区信息:
- 查看设备启动日志中的分区表(
cat /proc/mtd)。 - 分析U-Boot环境变量中的
mtdparts参数。 - 使用Binwalk的
-A参数进行架构分析,辅助判断分区边界。
4.2.3 flashrom:硬件级Flash读写
flashrom是一款开源的Flash芯片读写工具,支持通过多种编程器接口(如CH341A、FT2232H、Raspberry Pi GPIO等)直接操作Flash芯片。其优势在于:
- 芯片自动识别:自动检测芯片型号与容量。
- 读写校验:支持读取后校验,确保数据完整性。
- 分区操作:可对Flash的特定区域进行读写。
使用flashrom读取SPI NOR Flash的典型流程:
# 检测编程器与芯片
flashrom -p ch341a_spi
# 读取完整Flash
flashrom -p ch341a_spi -r backup.bin
# 写入固件(谨慎操作)
flashrom -p ch341a_spi -w new_firmware.bin
4.3 实战案例:从某品牌智能摄像头提取固件并还原文件系统
本案例以一款基于海思Hi3518E方案的智能摄像头为例,完整演示从硬件Flash读取到文件系统提取的全过程。
4.3.1 背景与目标
该摄像头为某厂商生产的家用云台摄像头,固件未在官网公开。测试目标为获取设备当前运行的完整固件,并提取文件系统进行后续漏洞分析。设备硬件信息:主控Hi3518E,板载SPI NOR Flash芯片为Winbond W25Q128(16MB)。
4.3.2 硬件准备与连接
拆开设备外壳后,在PCB板上找到W25Q128芯片。使用CH341A编程器配合测试夹连接芯片引脚。连接时注意芯片的VCC、GND、CLK、MOSI、MISO、CS引脚对应关系。连接完成后,在Linux主机上执行:
# 确认编程器识别
lsusb | grep CH341
# 检测Flash芯片
flashrom -p ch341a_spi
检测结果输出芯片型号为W25Q128,容量16MB,确认连接无误。
4.3.3 读取Flash镜像
# 读取完整Flash到文件
flashrom -p ch341a_spi -r camera_flash.bin
# 校验文件大小与哈希
ls -l camera_flash.bin
sha256sum camera_flash.bin
读取耗时约2分钟,得到16MB的完整镜像文件。使用binwalk进行初步扫描:
binwalk camera_flash.bin
扫描结果显示在偏移量0x100000处存在U-Boot镜像,在0x500000处存在LZMA压缩数据,在0x900000处存在squashfs文件系统。根据Hi3518E的典型分区布局,推测分区结构如下:
| 分区 | 偏移量 | 大小 | 内容 |
|---|---|---|---|
| Bootloader | 0x000000 | 0x100000 | U-Boot |
| Kernel | 0x100000 | 0x400000 | Linux内核(LZMA压缩) |
| Rootfs | 0x500000 | 0x400000 | squashfs文件系统 |
| Config | 0x900000 | 0x100000 | 配置参数 |
| APP | 0xA00000 | 0x600000 | 应用程序 |
4.3.4 提取文件系统
使用dd按分区偏移量切割出rootfs:
# 提取squashfs文件系统
dd if=camera_flash.bin of=rootfs.squashfs bs=1 skip=$((0x500000)) count=$((0x400000))
# 使用unsquashfs解包
unsquashfs rootfs.squashfs
解包成功后,在squashfs-root目录下看到完整的文件系统结构,包括/etc、/usr、/bin、/www等目录。进一步分析发现:
/etc/passwd中存在默认root密码哈希。/www目录下存在Web管理界面源码,包含多个PHP文件。/usr/bin下存在厂商自定义的二进制程序,可进行后续逆向分析。
4.3.5 案例复盘与经验总结
本案例的成功关键在于:
- 硬件识别准确:通过芯片丝印和编程器检测双重确认芯片型号。
- 分区边界判断:结合Binwalk扫描结果与设备典型布局,准确切割分区。
- 工具链配合:flashrom负责硬件读取,dd负责精确切割,unsquashfs负责文件系统解包,各司其职。
潜在风险与代价:拆机过程可能损坏外壳或排线;测试夹连接不当可能短路损坏芯片;读取过程中断电可能导致数据不完整。建议在操作前做好防静电措施,并多次读取比对哈希值确保数据一致性。
4.4 常见误区与操作要点
4.4.1 误区一:Binwalk提取失败即认为固件加密
Binwalk扫描不到文件系统签名,并不一定意味着固件被加密。可能的原因包括:
- 文件系统类型不支持:如ubifs、jffs2等需要特定工具处理。
- 固件头部有自定义格式:厂商可能添加了自定义头部,需要手动去除。
- 分区偏移未对齐:尝试使用
binwalk -A进行架构分析,或手动尝试不同偏移。
binwalk -E查看熵值分布。如果整个固件熵值接近1.0(高熵),则很可能被加密或压缩;如果存在明显的低熵区域,则说明仍有明文数据可分析。
4.4.2 误区二:忽略OTA包的加密与签名机制
现代IoT设备普遍对OTA包进行加密和签名,直接抓包获取的OTA包往往无法直接提取。应对策略包括:
- 分析固件中的OTA客户端代码,寻找解密密钥或算法。
- 提取设备中的安全芯片(如ATECC608A)中的密钥。
- 尝试降级攻击,获取未加密的旧版本OTA包。
4.4.3 误区三:dd提取时忽略字节序与块大小
dd命令的bs参数设置不当会导致提取数据错位。建议使用bs=1配合skip和count以字节为单位精确操作,虽然速度较慢但准确性最高。对于大文件,可先使用bs=1024计算块数,再结合skip和count进行提取。
4.4.4 操作要点清单
- 备份优先:任何写入操作前,务必完整备份原始Flash内容。
- 校验一致性:读取完成后,至少计算两次哈希值进行比对。
- 记录环境信息:记录芯片型号、编程器型号、连接方式、软件版本,便于复现。
- 分区表分析:优先从
/proc/mtd、U-Boot环境变量中获取分区信息,减少猜测。 - 工具版本管理:Binwalk的签名库需要定期更新,使用
binwalk --update保持最新。