【IOT路由器固件解密】Ghidra逆向获取key和文件格式解析实战
字数 1477 2025-08-22 12:23:13
IoT路由器固件解密:Ghidra逆向获取key和文件格式解析实战
1. 背景介绍
本文详细记录了如何通过逆向工程解密D-Link路由器加密固件的过程。固件版本从v1.04(未加密)升级到v1.10(加密),必须经过中间版本v1.04才能升级到v1.10,无法跳跃升级。
2. 初步分析
2.1 固件对比分析
使用binwalk工具分析两个版本固件:
未加密固件(v1.04):
binwalk -Me FW104B02_Middle_FW_Unencrypt.bin
结果显示可以正常解析出uImage头、LZMA压缩数据等结构。
加密固件(v1.10):
binwalk -Me FW110B02_FW_Encrypt.bin
结果显示无法解析文件系统,仅识别出QNX4 Boot Block。
2.2 加密检测方法
判断固件是否加密的方法:
binwalk -E查看熵值 - 接近1且无变化可能为加密binwalk -Me强制解析 - 能解析为压缩,不能解析为加密
3. 逆向工程分析
3.1 关键文件发现
在未加密固件中发现:
- RSA公钥文件:
/etc_ro/public.pem - 解密程序:
/bin/imgdecrypt(ELF格式,MIPS架构)
3.2 Ghidra逆向分析
使用Ghidra逆向imgdecrypt文件,发现关键函数:
解密函数:
int decrypt_firmare(int param_1, undefined4 *param_2, undefined4 param_3, undefined4 param_4) {
// ... 初始化变量 ...
local_20 = "/etc_ro/public.pem";
// ... 密钥生成和打印逻辑 ...
printf("key:");
for (num = 0; num < 0x10; num = num + 1) {
printf("%02X", (uint)*(byte *)((int)&local_18 + num));
}
puts("\r");
// ... 解密操作 ...
}
关键函数调用链:
FUN_00402554- 处理密钥FUN_0040108c- 包含AES加解密逻辑
3.3 密钥提取
通过分析逆向代码,发现:
- AES密钥:
358790034519f8c8235db6492839a73f - IV值:
98c9d8f0133d0695e2a709c8b69682d4 - 加密数据:
\xc8\xd3\x2f\x40\x9c\xac\xb3\x47\xc8\xd2\x6f\xdc\xb9\x09\x0b\x3c
使用OpenSSL解密获取最终密钥:
printf "\xc8\xd3\x2f\x40\x9c\xac\xb3\x47\xc8\xd2\x6f\xdc\xb9\x09\x0b\x3c" | \
openssl aes-128-cbc -d -nopad \
-K "358790034519f8c8235db6492839a73f" \
-iv "98c9d8f0133d0695e2a709c8b69682d4" | hd
输出密钥:c0 5f bf 19 36 c9 94 29 ce 2a 07 81 f0 8d 6a d8
4. 模拟执行获取密钥
使用QEMU模拟执行环境获取密钥:
- 安装qemu-user-static:
sudo apt install qemu-user-static
- 确认文件架构:
readelf -h ./bin/imgdecrypt
结果显示为MIPS架构,32位,小端序
- 模拟执行:
cp /usr/bin/qemu-mipsel-static .
sudo chroot . ./qemu-mipsel-static ./bin/imgdecrypt FW110B02_FW_Encrypt.bin
输出密钥:key:C05FBF1936C99429CE2A0781F08D6AD8
5. 固件解密过程
5.1 固件结构分析
加密固件二进制格式:
- 魔数字节:
53485253 - 固件解密区域大小:
00CA6ABB - 加密区域大小:
00CA6AC0 - IV值:
67C6697351FF4AEC29CDBAABF2FBE346 - SHA512校验值(3个)
- 未使用区域
- 解密/加密算法区域(各512字节)
- 填充区域
5.2 具体解密步骤
- 提取加密区域:
dd iflag=skip_bytes,count_bytes if=FW110B02_FW_Encrypt.bin \
of=Bin_Encrpted.bin skip=1756 count=13265600
- 验证SHA512:
sha512sum Bin_Encrpted.bin
应与固件中的加密区域SHA512值一致
- 使用OpenSSL解密:
openssl aes-128-cbc -d -p -nopad -nosalt \
-K C05FBF1936C99429CE2A0781F08D6AD8 \
-iv 67C6697351FF4AEC29CDBAABF2FBE346 \
-in Bin_Encrpted.bin -out Bin_Decrpted.bin
- 提取固件:
dd iflag=skip_bytes,count_bytes if=Bin_Decrpted.bin \
of=Bin_Firmware.bin count=13265595
- 追加密钥(签名):
perl -e 'print pack "H*", "C05FBF1936C99429CE2A0781F08D6AD8"' >> Unencrypted_Firmware.bin
- 验证解密结果:
sha512sum Unencrypted_Firmware.bin
应与固件中的解密固件区域SHA512值一致
- 使用binwalk解析:
binwalk -Me Unencrypted_Firmware.bin
6. 总结
本教程详细展示了:
- 通过binwalk初步分析固件加密状态
- 从未加密固件中寻找关键文件和线索
- 使用Ghidra逆向分析解密程序
- 提取AES密钥和IV值的方法
- 两种获取密钥的方式(逆向分析和模拟执行)
- 完整的加密固件解密流程
- 固件二进制结构分析
关键点:
- 必须通过中间版本升级的机制
- 公钥文件的位置和作用
- 逆向分析中的密钥生成逻辑
- 正确的OpenSSL解密参数和顺序
- 固件结构中的校验机制
- 最终需要追加密钥作为签名
通过这套方法,可以成功解密加密的IoT设备固件,为进一步的安全分析奠定基础。