当我们需要进行固件分析时,首先要做的就是获取固件,而获取固件无外乎就是从官网获取固件、通过流量拦截获取固件、使用编程器从闪存中读取固件以及通过串口调试提取固件。提取到固件之后,下一步就是对固件的进行分析,分析的对象主要是固件的内核与文件系统,包括Web应用、协议、核心控制程序等。
但是现在大多数厂商对了保证自己家产品安全,防止被他人攻击,就会对固件进行加密处理,可能是使用AES、DES、SM4等复杂的加密方式,也可能是使用XOR、ROT等简单的加密方式,加解密的程序一般放于Boot loader、内核或者文件系统中。这种情况下我们就不能直接使用 binwalk
等工具提取,需要先对加密的固件进行解密。
而厂商对固件的加密一般以下面三种情况为主:
设备固件在出厂时未加密(假设此时的版本是 v1.0),也未包含任何解密释序。厂商后续会发布一个包含解密程序的 v1.1 版本的未加密固件,最后再发布一个含有解密程序的 v1.2 版本的加密固件。此时,我们可以从固件 v1.1 中获取解密程序,用它来解密 v1.2 版本的固件,然后进行固件提取。
厂商直接在设备固件的原始版本中进行了加密,但是厂商决定更改加密方案并发布一个未加密的 v1.2 版本的新固件作为过渡,其中包含了新版本的解密程序。
在更新固件版本之前,需要先看新固件版本的发布通告,这个通告会指示用户在将固件升级到最新版本之前,需要先升级到固件的一个中间版本,而这个中间版本就是这个未加密的固件版本。通过这个中间版本的固件进行升级,最终可获取新版本加密固件的解密程序。
从网上下载的设备固件在原始版本中进行了加密,厂商决定更改加密方案并发布一个带新版解密程序的中间版迭代加密固件,但是由于对初始版本的固件就进行了加密,因此很难获得解密程序。
此时,想对加密后的固件进行解密会比较困难。针对这种情况,一种思路是购买设备并使用 JTAG
、UART
调试等方法进入 Linux Shell
或者 Uboot Shell
,直接从设备硬件中提取固件的文件系统。然后就是对固件进行更深层次的分析,看看如何能够对加密的固件进行逆向分析,得到加密逻辑,最后破解。
无设备情况下的通用思路如下
这里以 D-Link DIR-822-US 系列路由器 3.15B02 版本的固件为例进行分析。
该固件可以在官网中下载得到
下载完后,我们如果用binwalk去分析固件会发现报告是空白
我们这个时候可以用 binwalk -E
命令来查看固件的熵值(查看熵值是一种确认给定的字节序列是否压缩或加密的有效手段。熵值越大,意味着字节序列有可能是加密的或者是压缩过的)
这里显示熵值几乎都是1,这意味着这个固件的各个部分都进行了加密
幸运的是,我们发现对应版本固件的发布说明中提到了The firmware v3.15 must be upgraded from the transitional version of firmware v303WWb04_middle.
结合之前固件的三种加密更新方式,这个 firmware v303WWb04_middle
很可能就含有解密程序的中间过渡用未加密固件。所以我们就可以想办法下载这个固件并找到解密方案,从而解密 DIR822C1_FW315WWb02
固件。
这个固件我们可以去D-Link搭建的FTP服务器里下载(嫌麻烦可以在附件下载)
该中间过渡用的版本的固件没有加密,可以 binwalk -ME
直接提取
因为加密固件是由该未加密固件升级而来,所以我们可以在 squashfs-root
文件夹内搜索update
、firmware
、upgrade
、download
等关键的字符串
最终可以在 /etc/templates/hnap/StartFirmwareDownload.php
文件中找到线索,在浏览器中访问该文件就会执行下载固件的操作,这里有一行注释为 // fw encimg
,对应意思就是 firmware
、encryption
、image
前两行代码是用于获取固件映像签名的命令,使用 setattr
函数将属性 /runtime/tmpdevdata/image_sign
设置为 cat /etc/config/image_sign
,再使用 query
函数从属性 /runtime/tmpdevdata/image_sign
中获取固件映像签名,并将其存储在变量 $image_sign
中。
即变量 $image_sign
将被设置为 wrgac43s_dlink.2015_dir822c1
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2024-3-23 23:25
被Arahat0编辑
,原因: