3、固件获取与提取:从官网/设备/OTA包获取固件、binwalk工具使用、固件解包与文件系统挂载
做固件安全分析,第一步就是拿到固件。这一步看似简单,但坑特别多。我见过不少新手,花了两天时间分析一个假固件,最后发现是从第三方论坛下载的被篡改版本。所以,咱们先聊聊怎么靠谱地拿到固件。
3.1 固件获取的三种主要途径
说白了,固件来源就三条路:官网、设备本身、OTA升级包。每条路都有自己的门道。
3.1.1 从官网获取
这是最直接的方式。厂商通常会在技术支持页面提供固件下载。我个人习惯是优先走这条路,因为官网固件一般没被改过。
但要注意几点:
- 版本匹配:下载前确认硬件版本号。我遇到过某路由器,v1和v2的固件不通用,刷错直接变砖。
- 校验文件:很多厂商会提供MD5或SHA256值。下载后一定要算一下,防止下载损坏或被中间人篡改。
- 隐藏链接:有些厂商把固件藏得深。可以试试在URL里加
/firmware/或/download/路径,或者直接看网页源码找下载链接。
3.1.2 从设备中提取
如果官网没有固件,或者你需要的是设备当前运行的版本,那就得从设备里硬取。常用的方法有:
- 串口/UART读取:接上串口线,在bootloader阶段中断启动,进入uboot命令行。然后用
tftp或loadb命令把固件dump出来。 - JTAG/SWD调试:对于有调试接口的设备,可以直接读取Flash内容。这需要硬件调试器,比如J-Link或OpenOCD。
- 编程器读取:最暴力也最可靠的方法。把Flash芯片吹下来,用编程器读。嗯,这招我一般留到最后用,毕竟有物理损坏风险。
3.1.3 从OTA包中捕获
OTA升级包是另一个重要来源。很多智能设备会定期从服务器拉取更新。捕获OTA包的方法:
- 抓包工具:用Wireshark或tcpdump抓取设备与升级服务器之间的流量。注意HTTPS加密的流量需要中间人攻击(MITM)才能解密。
- 模拟升级服务器:修改设备的DNS解析,把升级域名指向本地搭建的服务器。然后等设备来请求固件,你就能拿到完整的OTA包。
- 逆向升级客户端:有些设备会把OTA包先下载到临时目录。如果你有设备root权限,可以直接去
/tmp或/cache目录找。
为什么会这样?因为很多厂商对OTA包的保护不够,甚至直接明文传输。我曾在某智能摄像头的OTA包里,直接看到了硬编码的云平台密钥。
3.2 binwalk工具使用
拿到固件后,第一件事就是分析它的结构。binwalk是我最常用的工具,没有之一。它就像固件分析的瑞士军刀。
3.2.1 安装与基本用法
安装很简单:
# 从GitHub克隆
git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python3 setup.py install
# 或者用pip
pip3 install binwalk
基本扫描命令:
binwalk firmware.bin
输出会列出固件中所有可识别的文件系统、压缩包、内核镜像等。我习惯先跑一遍这个,看看固件的大致构成。
3.2.2 常用参数
| 参数 | 作用 | 我的使用场景 |
|---|---|---|
-e |
自动提取识别的文件 | 一键解包,省事 |
-M |
递归扫描提取出的文件 | 对付多层嵌套的固件 |
-T |
显示文件类型详情 | 确认具体是什么格式 |
-D |
自定义提取规则 | 提取特定类型的文件 |
-A |
扫描CPU架构信息 | 判断是ARM还是MIPS |
binwalk -Me firmware.bin 是我最常用的组合。它会自动提取并递归扫描,基本能搞定80%的固件。
3.2.3 实战案例:识别加密固件
有一次我拿到一个路由器固件,binwalk扫描结果全是乱码,什么文件系统都没识别出来。我当时就怀疑固件被加密了。
怎么验证?看熵值:
binwalk -E firmware.bin
如果熵值接近1.0(最大值),说明数据是随机的,大概率加密了。如果熵值在0.5-0.8之间,说明有结构化的数据,可能只是压缩或混淆。
对于加密固件,你需要找到解密密钥或算法。这通常需要逆向分析uboot或升级程序。嗯,这里要注意,有些厂商只是简单做了XOR加密,用binwalk -X可以尝试暴力破解。
3.3 固件解包与文件系统挂载
binwalk提取出文件后,我们通常需要挂载文件系统来查看具体内容。最常见的嵌入式文件系统是SquashFS和JFFS2。
3.3.1 解包SquashFS
SquashFS是只读压缩文件系统,广泛用于路由器、摄像头等设备。解包方法:
# 安装工具
sudo apt-get install squashfs-tools
# 解包
unsquashfs rootfs.squashfs
# 或者指定输出目录
unsquashfs -d ./extracted_rootfs rootfs.squashfs
解包后,你会得到一个完整的文件系统目录。里面通常有/bin、/etc、/usr等标准Linux目录结构。
binwalk -R手动指定偏移量就能解包。
3.3.2 挂载JFFS2文件系统
JFFS2是日志型文件系统,常用于Nor Flash。挂载步骤:
# 创建挂载点
mkdir /mnt/jffs2
# 挂载(需要mtdblock设备)
modprobe mtdblock
modprobe jffs2
dd if=firmware.jffs2 of=/tmp/jffs2.img
losetup /dev/loop0 /tmp/jffs2.img
mount -t jffs2 /dev/loop0 /mnt/jffs2
注意,JFFS2挂载需要内核支持。如果你在普通Linux上操作,可能需要编译内核模块。我个人建议用虚拟机或Docker环境,省去配置麻烦。
3.3.3 处理其他文件系统
除了SquashFS和JFFS2,还会遇到:
- CramFS:老式压缩文件系统,用
cramfsck或cramfsswap处理 - UBIFS:用于NAND Flash,用
ubireader或ubi_reader工具 - YAFFS2:另一种NAND Flash文件系统,用
unyaffs解包 - Initramfs:内核启动用的临时文件系统,用
cpio解包
你想想看,如果每个文件系统都要手动处理,那得多累。所以我写了个脚本,自动识别文件系统类型并调用对应工具。后面章节会分享这个脚本。
3.4 本章知识体系
下面这张图总结了固件获取与提取的核心流程:
这张图把固件获取与提取的流程串起来了。从获取固件开始,经过binwalk分析,最后到文件系统处理,每一步都有对应的工具和方法。
好了,这一章的内容就到这里。记住,拿到固件只是开始,真正的挑战在后面。下一章我们会深入分析固件中的二进制文件,看看怎么从里面挖出漏洞。
公众号:蓝海资料掘金营,微信deep3321