第三章:固件获取与预处理

做固件逆向,第一步不是反汇编,也不是找漏洞。

第一步是——拿到固件。

听起来简单,对吧?但我在实际项目中遇到过太多次,花了两周时间逆向一个固件,最后发现拿到的版本是错的。那种感觉,就像你拆了一台机器,发现图纸拿错了。所以这一章,咱们把固件获取和预处理这件事聊透。

3.1 固件获取途径

固件从哪来?说白了就三条路:官网、OTA、硬件提取。我按优先级给你排个序。

3.1.1 官网下载

这是最省事的途径。大部分厂商会在官网提供固件更新包,尤其是路由器、智能家居这类设备。

我个人习惯是先去官网的「支持」或「下载中心」页面翻一翻。有时候固件藏在「固件历史版本」里,有时候在「技术文档」的附件里。嗯,这里要注意——有些厂商会把固件打包成.exe自解压文件,你得先解包才能拿到真正的.bin文件。

小技巧: 用浏览器的开发者工具(F12)抓一下下载链接的请求,有时候能发现隐藏的固件仓库路径。我在一个摄像头固件里就这么挖到过内部测试版。

3.1.2 OTA升级包抓取

官网没有?那就等设备自己升级。OTA(Over-The-Air)升级包通常通过HTTP或HTTPS传输。

怎么抓?我常用的方法:

  • 在电脑上开一个Wi-Fi热点,让设备连上来
  • 用Wireshark或Charles抓包,过滤HTTP请求
  • 找到包含.bin.fw.img后缀的URL

我曾经抓过一个智能门锁的OTA包,发现它用的是明文HTTP传输。固件里连管理员密码都写死在代码里——这种案例,你逆向多了就见怪不怪了。

注意: 有些设备会校验OTA包的签名。你抓到的包可能被加密或签名,需要后续解密才能用。别慌,后面会讲怎么处理。

3.1.3 硬件提取

官网没有,OTA抓不到?那就只能上硬件了。

硬件提取常见手段:

  • SPI Flash读取: 用编程器(如CH341A、树莓派)直接读Flash芯片
  • JTAG/SWD调试接口: 通过调试接口dump内存
  • U-Boot控制台: 如果能进U-Boot,用mdmw命令读内存

我建议你手边常备一个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写个脚本,遍历常见密钥(如0xAA0xFF0x55)。

# 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
核心思路: 解密的关键是找到密钥。密钥可能在Bootloader里、在设备配置分区里、或者干脆是固定的。多翻翻厂商的SDK文档,有时候密钥就写在README里。

3.3 固件压缩与解压缩

解密之后,下一步是解压缩。固件为了节省空间,通常会压缩。

常见的压缩格式:

  • gzip: 文件头1F 8B 08,用gunzip或Python的gzip模块解压
  • LZMA: 文件头5D 00 00,用7zlzma工具
  • 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 本章知识体系

说了这么多,我画个图帮你理清思路。固件获取与预处理的核心流程是这样的:

固件获取与预处理核心流程 固件获取 OTA抓取 硬件提取 固件解密(XOR/AES/自定义) 固件解压缩(gzip/LZMA/SquashFS) 完整性校验(MD5/SHA/签名)

这个流程走完,你手里拿到的就是一份干净、可分析的固件了。接下来就可以开始真正的逆向分析了。


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