第二章:固件获取与提取——从源头到文件系统
做固件安全分析,第一步就是拿到固件。这事儿听起来简单,但实际操作中坑不少。我刚开始做这行时,光找固件就花了两天,结果发现下载的是个空壳子……嗯,今天咱们就把固件获取和提取这件事彻底讲清楚。
2.1 固件获取的三大渠道
固件从哪来?说白了就三个地方:官网、设备本身、OTA升级包。我个人的习惯是优先从官网下手,因为最省事。但有些厂商的官网做得跟迷宫似的,你得有点耐心。
2.1.1 官网下载
大部分厂商会在官网提供固件下载,通常在「支持」或「下载中心」栏目。但要注意:
- 有些固件需要注册账号才能下载
- 部分厂商只提供最新版本,历史版本得自己找
- 文件名可能被混淆,比如改成 .bin 但实际是 .zip
2.1.2 从设备中提取
如果你手头有设备,那直接从设备里读固件是最靠谱的。常见方法有:
- UART/串口: 设备启动时通过串口输出启动信息,有时能进入uboot或bootloader,直接dump固件
- JTAG/SWD: 通过调试接口直接读取Flash内容,适合有硬件基础的工程师
- SPI Flash编程器: 把Flash芯片焊下来,用编程器读取。这招比较暴力,但最彻底
2.1.3 OTA包捕获
OTA(Over-The-Air)升级包是另一个重要来源。我遇到过不少设备,官网不提供固件,但OTA升级时能抓到包。方法如下:
- 在手机或设备上设置代理(比如Burp Suite、Charles)
- 触发OTA升级,捕获HTTP/HTTPS请求
- 从请求中提取固件下载链接
- 如果用了HTTPS,可能需要安装CA证书来解密流量
避坑指南: 我曾经抓一个智能摄像头的OTA包,发现它用了自签名证书,而且证书校验不严格。我直接替换了CA证书,成功抓到了固件。但后来发现厂商已经修复了这个漏洞……嗯,动作要快。
2.2 固件提取的核心工具
拿到固件文件后,下一步就是把它拆开。固件通常是一个大二进制文件,里面包含了文件系统、内核、bootloader等。我们需要用工具把它「解包」。
2.2.1 Binwalk——最常用的固件分析工具
Binwalk 是我用得最多的工具,没有之一。它能自动识别固件中的文件系统、压缩数据、内核镜像等。
# 基本用法:扫描固件中的文件
binwalk firmware.bin
# 提取所有识别到的文件
binwalk -e firmware.bin
# 指定提取目录
binwalk -e -M --dd=".*" firmware.bin
Binwalk 的工作原理是扫描文件中的魔数(Magic Number)。比如 SquashFS 文件系统以 hsqs 开头,JFFS2 以 0x1985 开头。它会把这些片段切出来。
2.2.2 dd——手动切割的瑞士军刀
当 Binwalk 识别不出来时,就得靠 dd 手动切割了。dd 是 Linux 下的一个底层工具,可以按字节精确复制数据。
# 从偏移量 0x100000 开始,读取 4MB 数据
dd if=firmware.bin of=output.bin bs=1 skip=$((0x100000)) count=$((4*1024*1024))
# 常用参数说明
# if:输入文件
# of:输出文件
# bs:块大小(通常设为1,方便按字节操作)
# skip:跳过多少字节
# count:读取多少字节
怎么知道偏移量?通常靠经验或分析固件的启动日志。比如 U-Boot 启动时会打印各分区的起始地址和大小,记下来就能用 dd 切了。
2.2.3 Unblob——新一代固件提取工具
Unblob 是近几年出现的工具,专门解决 Binwalk 处理不了的复杂固件。它支持更多的文件系统类型,而且能处理嵌套压缩的情况。
# 安装
pip install unblob
# 使用
unblob firmware.bin -o output_dir
Unblob 的优势在于:
- 支持 LZMA、LZ4、Zstd 等现代压缩算法
- 能自动处理多层嵌套(比如 SquashFS 里面又包了一个 cpio)
- 对损坏的固件有更好的容错性
我的对比: 有一次分析一个智能门锁的固件,Binwalk 只识别出了内核,文件系统死活找不到。换成 Unblob 后,它直接解出了 SquashFS,还附带了一个隐藏的配置文件。从那以后,我工具箱里就多了 Unblob。
2.3 固件提取的完整流程
下面这张图展示了固件获取与提取的完整流程,我画了个 SVG 方便你理解:
2.4 实战:提取一个典型的路由器固件
咱们拿一个典型的路由器固件练练手。假设你从官网下载了 router_fw.bin,大小约 16MB。
# 第一步:用 Binwalk 扫描
binwalk router_fw.bin
# 输出示例:
# DECIMAL HEXADECIMAL DESCRIPTION
# 0 0x0 uImage header, header size: 64 bytes
# 64 0x40 LZMA compressed data, properties: 0x5D
# 1310720 0x140000 SquashFS filesystem, little endian, version 4.0
# 第二步:提取文件系统
binwalk -e router_fw.bin
# 第三步:查看提取结果
ls _router_fw.bin.extracted/
# 应该能看到 squashfs-root 目录,里面就是文件系统
如果 Binwalk 没识别出来,试试 Unblob:
unblob router_fw.bin -o output_dir
ls output_dir/
# 可能看到多个子目录,每个对应一个提取出的组件
0xDEADBEEF——明显是厂商自定义的魔数。我查了芯片手册,发现文件系统其实是标准的 SquashFS,只是头部被改了。手动去掉前 256 字节后,Binwalk 就能正常识别了。
2.5 常见文件系统类型
提取出来的文件系统,常见的有这几种:
| 文件系统类型 | 魔数 | 常见场景 | 挂载命令 |
|---|---|---|---|
| SquashFS | hsqs |
路由器、IoT设备 | mount -t squashfs -o loop file.squashfs /mnt |
| JFFS2 | 0x1985 |
嵌入式Linux设备 | mount -t jffs2 -o loop file.jffs2 /mnt |
| ext4 | 0xEF53 |
较新的设备、Android | mount -t ext4 -o loop file.ext4 /mnt |
| cpio | 070701 |
initramfs、内核模块 | cpio -idmv < file.cpio |
| UBIFS | UBI# |
NAND Flash设备 | 需使用 ubiattach + mount |
总结一下: 固件获取与提取是固件安全分析的基础。官网下载最方便,设备提取最彻底,OTA包捕获适合「无官网」场景。工具方面,Binwalk 是首选,dd 用于手动切割,Unblob 处理复杂情况。记住,没有万能工具,多备几把「刀」总没错。
嗯,这一章的内容就到这。下一章咱们会深入文件系统内部,看看怎么分析里面的二进制文件。但那是后话了,先把今天的工具练熟再说。
公众号:蓝海资料掘金营,微信deep3321