Vigor3910 固件解密
固件解密分析:DrayTek Vigor3910 固件
固件信息:
Draytek Vigor 3910是Draytek旗下的一款多WAN安全路由器。** *厂商:Draytek* *型号:Vigor 3910* **固件版本:3971、4325
使用 binwalk 进行初步分析
为了了解固件的结构和加密状态,我们可以使用 binwalk 工具进行分析。以下是具体步骤和发现:
熵值分析
通过以下命令查看固件的熵值分布:
1 | binwalk -E firmware.bin |
![image-
结果:分析显示固件的熵值接近 1。
熵值含义:
- 熵值(entropy)是衡量数据随机性的指标,范围从 0 到 1。
- 熵值接近 0 表示数据高度有序(如纯文本或重复模式)。
- 熵值接近 1 表示数据高度随机,通常是压缩或加密的特征。
结论:固件的熵值接近 1,表明其内容并非明文或简单压缩,而是经过加密处理。
中间过渡版本分析
为了寻找未加密的中间过渡件,我们回溯历史版本,下载 V3.9.7.1:
- 文件:v3910_3972.all(假设为 V3.9.7.1)。
- 提取尝试
1 | binwalk -Me v3910_3972.all |
熵值检查:
1 | binwalk -E v3910_3972.all |
结果:熵值较低,表明 V3.9.7.1 未加密。
稍微分析一下
固件基本结构
固件通常包含以下部分:
- Bootloader:硬件初始化和内核加载,位于固件开头。
- Kernel:操作系统核心,通常压缩(如 LZMA、gzip)。
- Rootfs:用户空间文件系统,包含脚本、二进制和多媒体内容,常以压缩格式存储(如 LZ4、gzip)。
未加密固件分析 (V3.9.7.1)
- 结构分析
1
binwalk v3910_3972.all
结果:偏移 0xEE3C48(十进制 15613000)标记为 LZ4 compressed data, legacy,确定为文件系统起点。
依据:
- LZ4 压缩常见于 initramfs 或 rootfs。
- 后续包含脚本、图像和路径,符合文件系统特征。
- 位于内核之后,符合固件布局。
使用dd命令提取这部分的文件系统
1 | dd if=v3910_3972.all of=gizp.bin bs=1 skip=15613000 |
这里为了方便就直接从这里开始提取后面的全部
binwalk并不支持lz4解压缩,故我们下载liblze4-tool,并在binwalk的配置文件中添加规则,(路径看shell图片的路径)
1 | ^lz4 compressed data:lz4:lz4 -d '%e' '%e.bin' |
1 | sudo apt-get install liblz4-tool |
们再次使用binwalk -Me固件,到这里就得到了最开始没有加密的固件系统,
从未加密到加密的过渡
V3.9.7.1 未加密,而 V4.4.3.1 已加密,说明固件升级引入了加密机制。我们在 V3.9.7.1 的文件系统中搜索升级逻辑:
- 搜索关键字
1 | grep -r "upgrade" |
发现:fw_upload 文件包含 “upgrade” 和 “firmware”,为固件升级脚本。
解密逻辑:
对此二进制文件进行一些基础的信息收集,可以知道其为arm64的小端序
准备 QEMU:通过cp把qemu-aarch64-static移动到当前目录下,去运行此程序
1 | cp $(which qemu-aarch64-static) ./ |
报错:Bad input data in argv,缺少输入输出文件。
1 | sudo chroot . ./qemu-aarch64-static ./sbin/chacha20 |
仍报错:参数格式可能不正确。
1 | sudo chroot . ./qemu-aarch64-static ./sbin/chacha20 v3910_4326.all |
逆向分析 chacha20
- 工具:IDA Pro。
- 通过IDA对此二进制程序进行逆向分析发现里面会存在key
这里找到key了我们还需要他的nonce随机数,
在加密的固件头信息中发现了这个值,
要知道加密的固件是从enc_Image之后开始的,所以我们要提取被加密的部分,
这里的 enc_Image 指的是固件中某个标记或区域的名称,通常在固件解包后会生成类似 enc_Image 的文件,表示加密的镜像部分。
注意这里怎么去提,image后面的一个byte是是enc固定的大小,这里是小端序所以就是034B1A00,这个转成10进制就是55253504,这个就是被加密的数据的长度或者大小,(个人理解)
所以我们应该是从243开始提,216+25+3
这里就是被加密的数据,所以我们使用dd命令去提
1 | dd if=v3910_4325.all of=test skip=243 count=55187968 bs=1 |
那么我们知道的是,chacha20已经被集成在许多语言中的库里了,故我们用python去写一个
解密的脚本即可(因为原程序参数我们不知道该放什么故想着写脚本去解密)
1 | from Crypto.Cipher import ChaCha20 |
解密成功,生成 test_decrypt。
参考链接
1、https://www.hexacon.fr/slides/hexacon_draytek_2022_final.pdf