第三章:固件获取与预处理
做固件逆向,第一步不是反汇编,也不是找漏洞。
第一步是——拿到固件。
听起来简单,对吧?但我在实际项目中遇到过太多次,花了两周时间逆向一个固件,最后发现拿到的版本是错的。那种感觉,就像你拆了一台机器,发现图纸拿错了。所以这一章,咱们把固件获取和预处理这件事聊透。
3.1 固件获取途径
固件从哪来?说白了就三条路:官网、OTA、硬件提取。我按优先级给你排个序。
3.1.1 官网下载
这是最省事的途径。大部分厂商会在官网提供固件更新包,尤其是路由器、智能家居这类设备。
我个人习惯是先去官网的「支持」或「下载中心」页面翻一翻。有时候固件藏在「固件历史版本」里,有时候在「技术文档」的附件里。嗯,这里要注意——有些厂商会把固件打包成.exe自解压文件,你得先解包才能拿到真正的.bin文件。
3.1.2 OTA升级包抓取
官网没有?那就等设备自己升级。OTA(Over-The-Air)升级包通常通过HTTP或HTTPS传输。
怎么抓?我常用的方法:
- 在电脑上开一个Wi-Fi热点,让设备连上来
- 用Wireshark或Charles抓包,过滤HTTP请求
- 找到包含
.bin、.fw、.img后缀的URL
我曾经抓过一个智能门锁的OTA包,发现它用的是明文HTTP传输。固件里连管理员密码都写死在代码里——这种案例,你逆向多了就见怪不怪了。
3.1.3 硬件提取
官网没有,OTA抓不到?那就只能上硬件了。
硬件提取常见手段:
- SPI Flash读取: 用编程器(如CH341A、树莓派)直接读Flash芯片
- JTAG/SWD调试接口: 通过调试接口dump内存
- U-Boot控制台: 如果能进U-Boot,用
md、mw命令读内存
我建议你手边常备一个CH341A编程器,几十块钱,但能解决80%的硬件提取问题。记得买带夹子的版本,不用拆焊芯片。
3.2 固件加密与解密
拿到固件文件后,别急着分析。先看看它是不是加密的。
怎么判断?看文件头。常见的固件头有:
| 文件头特征 | 可能类型 |
|---|---|
7F 45 4C 46 (ELF) |
未加密的Linux固件 |
1F 8B 08 (gzip) |
压缩固件 |
89 50 4E 47 (PNG) |
可能是伪装或加密 |
| 全0或随机字节 | 大概率加密了 |
如果文件头看起来像乱码,那八成是加密了。常见的加密方式有:
- XOR加密: 简单但常见,密钥可能是固定字节或设备序列号
- AES加密: 密钥通常藏在U-Boot或Bootloader里
- 自定义算法: 有些厂商自己写加密,逆向起来比较头疼
解密时,我一般先试试XOR。用010 Editor或Python写个脚本,遍历常见密钥(如0xAA、0xFF、0x55)。
# Python XOR解密示例
def xor_decrypt(data, key):
return bytes([b ^ key for b in data])
with open('encrypted.bin', 'rb') as f:
encrypted = f.read()
# 尝试常见密钥
for key in [0xAA, 0xFF, 0x55, 0x00]:
decrypted = xor_decrypt(encrypted, key)
if decrypted[:4] == b'\x7fELF': # 检查ELF头
print(f'找到密钥: 0x{key:02X}')
with open('decrypted.bin', 'wb') as out:
out.write(decrypted)
break
3.3 固件压缩与解压缩
解密之后,下一步是解压缩。固件为了节省空间,通常会压缩。
常见的压缩格式:
- gzip: 文件头
1F 8B 08,用gunzip或Python的gzip模块解压 - LZMA: 文件头
5D 00 00,用7z或lzma工具 - SquashFS: 文件系统镜像,用
unsquashfs解压 - JFFS2/UBIFS: 闪存文件系统,需要专用工具
我遇到过最坑的一次——固件先gzip压缩,再XOR加密,再倒序排列。厂商为了防逆向真是煞费苦心。你想想看,如果不知道这个处理顺序,直接解压肯定报错。
解压时,我推荐用binwalk这个神器。它能自动识别固件里的各种文件头和压缩格式。
# 用binwalk分析固件
binwalk firmware.bin
# 自动提取所有文件
binwalk -e firmware.bin
binwalk会递归解压,把固件里的内核、文件系统、配置分区都提取出来。嗯,这里要注意——binwalk有时候会误判,尤其是遇到自定义格式时。我建议手动验证一下提取结果。
3.4 固件完整性校验
最后一步,校验固件完整性。这一步很多人会跳过,但我建议你别省。
为什么要校验?
- 确保你拿到的固件没被篡改
- 确认解压过程没出错
- 验证固件版本是否正确
常见的校验方式:
- MD5/SHA1/SHA256: 厂商官网通常会提供哈希值,下载后对比一下
- CRC32: 固件头里可能包含CRC校验值
- 数字签名: 用厂商的公钥验证签名(如果有的话)
我曾经在分析一个路由器固件时,发现官网提供的MD5和我下载的不一致。后来发现是中间人攻击,有人篡改了固件。从那以后,我每次下载固件都会先校验哈希。
# Linux下计算哈希
sha256sum firmware.bin
# 对比官网提供的哈希值
echo "官网哈希值 firmware.bin" | sha256sum -c
3.5 本章知识体系
说了这么多,我画个图帮你理清思路。固件获取与预处理的核心流程是这样的:
这个流程走完,你手里拿到的就是一份干净、可分析的固件了。接下来就可以开始真正的逆向分析了。
公众号:蓝海资料掘金营,微信deep3321