第三章:固件获取与提取——从硬件到软件的完整链路

大家好,我是你们的固件安全讲师。今天我们来聊聊固件获取与提取这个环节。说实话,这是整个漏洞挖掘中最基础、也最容易被忽视的一步。我见过太多人拿着工具直接开搞,结果发现固件都没拿对——嗯,那后面的分析基本就是白费功夫。

固件获取,说白了就是解决一个问题:你要分析的二进制代码到底在哪? 它可能藏在芯片里、挂在官网上、或者躲在OTA升级包里。我们一条一条来看。

一、从硬件芯片读取固件

这是最硬核的方式。你手头有个设备,想直接扒它的固件。我个人习惯先看芯片型号,再决定用什么工具。

1.1 常见存储介质与接口

存储介质 常见接口 读取工具 注意事项
SPI Flash SPI (SOIC-8/16) CH341A、树莓派+spi闪存编程器 电压匹配,3.3V为主
NAND Flash 并行接口 专用NAND编程器 坏块管理,ECC校验
eMMC MMC协议 eMMC转接板+读卡器 需要焊接或飞线
NOR Flash 并行/SPI 通用编程器 容量小,速度快

我在项目中遇到过最头疼的情况:一个IoT设备用了BGA封装的NAND Flash,引脚间距0.5mm。飞线?那简直是噩梦。后来我直接买了块同型号的开发板,从开发板上读——这招叫「曲线救国」,你想想看,有时候换个思路比硬刚更有效。

1.2 实战:用CH341A读取SPI Flash

CH341A是入门神器,便宜又好用。但要注意,它默认输出5V,很多SPI Flash是3.3V的。我曾经因为没注意电压,直接烧掉了一块Flash——嗯,从那以后我每次都会先量一下VCC引脚电压。

# 连接方式(以SOIC-8为例)
# CH341A引脚 -> SPI Flash引脚
# 1 (CS)   -> 1 (CS#)
# 2 (DO)   -> 2 (SO)
# 3 (WP)   -> 3 (WP#)
# 4 (GND)  -> 4 (GND)
# 5 (DI)   -> 5 (SI)
# 6 (CLK)  -> 6 (SCK)
# 7 (HOLD) -> 7 (HOLD#)
# 8 (VCC)  -> 8 (VCC)

# 使用flashrom工具读取
sudo flashrom -p ch341a_spi -r firmware.bin

# 验证读取完整性
sha256sum firmware.bin
⚠️ 警告: 读取前务必确认芯片型号和电压。有些芯片有写保护引脚(WP#),需要拉高才能正常读取。我见过有人焊了半天读不出来,最后发现是WP#悬空了。

二、从官网/OTA获取固件

如果能从软件层面拿到固件,那当然比拆芯片省事多了。但这里有个坑:厂商往往不会把完整固件直接挂出来。

2.1 官网下载的常见套路

  • 技术支持页面:很多厂商会把固件放在「下载中心」或「技术支持」里,但文件名可能很隐晦。比如「FW_2024_03_15.bin」这种,你根本不知道它是什么版本。
  • FTP服务器:有些老牌厂商还在用FTP。我建议试试 ftp://ftp.厂商域名.com,匿名登录,说不定有惊喜。
  • GitHub Releases:开源项目或部分厂商会把固件源码或二进制放在GitHub上。记得看Tags和Releases。

2.2 OTA升级包的捕获与分析

OTA升级包通常经过加密或签名。但别怕,我们一步步来。

  1. 抓包工具:用Burp Suite或mitmproxy设置中间人代理,捕获设备与服务器之间的HTTP/HTTPS请求。
  2. 识别升级包:通常是一个大文件下载请求,URL里可能包含 updatefirmwareota 等关键词。
  3. 解密/解包:如果包体是加密的,需要逆向分析设备的解密逻辑。我遇到过一种情况:厂商用了简单的XOR加密,密钥就硬编码在二进制里——说白了,就是防君子不防小人。
# 用wget模拟OTA下载(假设已获取到URL)
wget https://ota.example.com/update/firmware_v2.1.0.bin

# 检查文件类型
file firmware_v2.1.0.bin

# 如果文件头是PK(ZIP格式),直接unzip
unzip firmware_v2.1.0.bin

# 如果是加密的,尝试常见解密方式
# 比如XOR解密(密钥0xAB)
python3 -c "
import sys
data = open('firmware_v2.1.0.bin', 'rb').read()
key = 0xAB
decrypted = bytes([b ^ key for b in data])
open('decrypted.bin', 'wb').write(decrypted)
"
💡 小技巧: 有些OTA包是分片传输的,比如先传头部信息,再传固件主体。抓包时注意看Content-Range头,可能需要合并多个请求才能得到完整固件。

三、固件解包与文件系统提取

拿到固件二进制文件后,下一步就是把它拆开。固件通常是一个大镜像,里面包含了Bootloader、内核、文件系统、配置数据等。我习惯先看文件头,判断它的格式。

3.1 常见固件格式与识别

格式 特征 常见于 解包工具
TRX 以"HDR0"开头 Broadcom路由器 trx_tool
U-Boot镜像 以"uImage"或"0x27051956"开头 嵌入式Linux设备 dumpimage
SquashFS 以"hsqs"或"sqsh"开头 只读文件系统 unsquashfs
JFFS2 以"0x1985"开头 可读写文件系统 jefferson
CPIO 以"070701"或"070702"开头 initramfs cpio

你想想看,如果连固件格式都认不出来,后面的分析根本无从下手。我建议先用 binwalk 扫描一遍,它能自动识别大部分常见格式。

3.2 使用binwalk进行固件分析

binwalk是我最常用的固件分析工具,没有之一。它就像固件的「CT扫描仪」,能把里面的结构一层层剥开。

# 扫描固件中的文件签名
binwalk firmware.bin

# 提取所有识别到的文件
binwalk -e firmware.bin

# 递归提取(处理嵌套的固件)
binwalk -Me firmware.bin

# 只提取特定偏移和大小的数据
binwalk -D 'squashfs:rootfs:squashfs' firmware.bin

我在项目中遇到过一个问题:binwalk扫描出来一堆东西,但文件系统提取失败。后来发现是固件头部有自定义校验,binwalk没识别出来。我手动跳过了前256字节,再跑一次——成功了。所以记住:工具是辅助,脑子才是核心

3.3 手动解包:当工具失效时

有时候厂商会魔改文件系统格式,或者加了自定义压缩。这时候就得手动来了。

  1. 查找文件系统偏移:用 hexdumpxxd 查看二进制,寻找文件系统魔数(Magic Number)。
  2. 计算大小:从魔数位置到文件末尾,或者根据固件头中的size字段。
  3. dd提取:用 dd if=firmware.bin of=rootfs.squashfs bs=1 skip=偏移量 count=大小 提取。
  4. 尝试挂载:如果是SquashFS,可以用 mount -o loop,ro -t squashfs rootfs.squashfs /mnt 直接挂载查看。
# 手动提取SquashFS文件系统
# 假设binwalk显示SquashFS在偏移0x100000,大小0x500000
dd if=firmware.bin of=rootfs.squashfs bs=1 skip=$((0x100000)) count=$((0x500000))

# 尝试挂载
sudo mount -o loop,ro -t squashfs rootfs.squashfs /mnt

# 如果挂载失败,可能是压缩方式不同
# 尝试unsquashfs
unsquashfs -d rootfs rootfs.squashfs
🔑 核心要点: 固件解包不是终点,而是起点。拿到文件系统后,重点关注 /bin/sbin/usr/bin 下的可执行文件,以及 /etc 下的配置文件。这些地方往往藏着漏洞。

知识体系总览

下面这张图是我自己画的,把本章的知识点串起来了。你可以把它当作一个检查清单:做固件获取时,按这个流程走,基本不会漏东西。

固件获取与提取流程 硬件芯片读取 官网/OTA获取 其他来源(二手/拆机) SPI Flash / NAND / eMMC CH341A / 编程器 / 飞线 注意电压匹配 验证完整性 下载 / 抓包 / 逆向 官网下载 / FTP / GitHub OTA抓包(mitmproxy) 解密/解签 二手设备 / 拆机 注意固件版本 可能被篡改 需要交叉验证 固件分析:binwalk / 手动分析 / 格式识别 TRX / U-Boot / SquashFS / JFFS2 / CPIO 提取文件系统 → 开始漏洞挖掘 /bin /sbin /etc 重点关注

嗯,这张图基本把固件获取的完整链路讲清楚了。从硬件读取到软件下载,再到解包提取,每一步都有坑,但也都有对应的解法。我个人觉得,最关键的还是多动手、多踩坑——经验这东西,光看书是学不来的。

📌 我的建议: 初学者可以先从官网下载固件开始练手,用binwalk解包,看看文件系统里都有什么。等熟悉了,再尝试从硬件芯片读取。别一上来就挑战BGA封装的NAND——那玩意儿连老手都头疼。

公众号:蓝海资料掘金营,微信deep3321