固件加解密思路与D-Link固件解密实战操作
加密固件更新的方式
固件制造商出于对产品安全的考虑,防止固件被恶意篡改,通常会采取各种防范手段,阻止固件被直接解包和破解。其中一种重要且有效的手段就是利用加密算法对固件进行加密,例如使用AES、DES等对称加密算法加密固件中的内核和文件系统,或使用XOR、ROT等简单置换算法对固件进行处理,这使得研究人员无法直接读取固件中的明文内容。
对固件进行解密之前,需提前了解厂商一般会以怎样的形式发布加密固件以及在设备启动和固件升级过程中,会在哪些地方对固件进行解密。厂商发布加密固件一般有以下三种场景:
1.固件出厂未加密,后续发布包含解密方案的未加密固件
设备固件在出厂时未加密(假设此时的版本是 v1.0),也未包含任何解密释序。解密程序与未加密版本的新版本固件(假设为 v1.1)一起提供,此后发布的固件为加密固件(假设为 v1.2)。此时,我们可以从固件v1.1中获取解密程序,用它来解密 v1.2 版本的固件,然后进行更新。
2.固件出厂加密,后续发布包含新版解密方案的未加密固件
设备固件在原始版本中进行了加密,厂商决定更改加密方案并发布一个未加密的新固件(假设为 v 1.2),其中包含了新版本的解密程序。
在更新固件版本之前,需要先看新固件版本的发布通告,这个通告会指示用户在将固件升级到最新版本之前,需要先升级到固件的一个中间版本,而这个中间版本就是未加密的固件版本。通过这个中间版本的固件进行升级,最终可获取新版本加密固件的解密程序。
3. 固件出厂加密,后续发布包含新版解密方案的加密固件
从网上下载的设备固件在原始版本中进行了加密,厂商决定更改加密方案并发布一个带新版解密程序的中间版迭代加密固件,但是由于对初始版本的固件就进行了加密,因此很难获得解密程序。
此时,想对加密后的固件进行解密会比较困难。针对这种情况,一种思路是购买设备并使用 JTAG、UART 调试等方法,从设备硬件中提取固件中的文件系统。我们能做的就是对固件进行更深层次的分析,看看如何能够对加密的固件进行破解。
常见的固件解密方法
针对物联网终端设备的固件解密,总结如下五种方法和技巧:
1.基于老版本未加密固件中的解密程序实现新版本加密固件的解密
对于固件出厂时未加密,后续发布的固件是加密的情况,可以通过对比边界版本,解包最后一个未加密版本逆向升级程序还原加密过程,以实现对加密固件的解密。
2.基于调试串口直接提取未加密固件
如果设备存在 UART、JTAG 等调试接口,可通过连接硬件接口获取设备的 Shell,从而 dump 出设备的固件。
但由于某些设备安全限制较高导致无法进入 Linux Shell,我们可尝试进入 BootLoader Shell(最常见的是 Uboot Shell)对固件进行提取。这里要说明的一点是部分设备更新固件后会将解密后的新版固件写回 Flash,这种情况下 dump 出的固件是未加密的,而相反的是部分设备Flash中的固件一直是加密状态存在,只是在每次设备启动时进行动态解密。所以此种方法提取出的固件可能也是加密的,但好处在于可以避免因拆解设备 Flash 去读固件导致设备损坏的风险,并且可以获取到较为完整的固件(官方下载的固件可能只是某块数据的更新包)。
3.基于管理服务获取设备Shell提取文件系统
对于有Telnet、SSH 等服务的设备,可以通过这些服务进入设备的 Linux Shell 进行固件提取。服务一般在设备的 web 管理页面中可手动开启,但需要说明的一点是某些厂商会开发自家的 CLI 屏蔽掉底层 Linux Shell,连接这些服务进入的 Shell 只是厂商的CLI,也无法提取文件系统,不过某些设备(光猫居多)的CLI存在可进入 Linux Shell 的命令,具体可自行在互联网上搜索相应的方法。
4.基于低版本固件RCE漏洞获取设备Shell分析解密逻辑实现对新版固件的解密
如果设备历史加密版本固件出现过 RCE 漏洞,可将存在漏洞的固件刷入设备,通过 RCE 漏洞获取设备 Linux Shell,再分析其包含的解密逻辑,最终通过该解密逻辑实现对更新版本固件的解密。需要注意的是存在 RCE 漏洞版本的固件所使用的加密方案需要与新版本固件一致。
5.直接分析完整固件中包含的解密逻辑实现对固件的解密
常见情况下固件的解密逻辑肯定是存在Flash中的,当获取到完整版固件(拆机从 Flash 读取或者从BootLoader Shell 中提取等)后,可以直接对整个固件进行逆向分析寻找解密逻辑代码实现对固件的解密,但此种方法难度较大,并且这类设备安全性一般较高,很有可能分析出了解密逻辑但拿不到解密密钥,如密钥单独存放在某个安全芯片中。
对加密的D-Link固件进行解密
准备工作
这里以 D-Link DIR-822-US 系列路由器 3.15B02 版本的固件为例进行分析。
该固件可以在官网 中下载得到
1
wget https://support.dlink.com/resource/PRODUCTS/DIR-822-US/REVC/DIR-822_REVC_FIRMWARE_v3.15B02.zip
下载完后,我们如果用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等关键的字符串
1
grep -rnw './' -e 'update\|firmware\|upgrade\|download'
最终可以在 /etc/templates/hnap/StartFirmwareDownload.php 文件中找到线索,在浏览器中访问该文件就会执行下载固件的操作,这里有一行注释为 // fw encimg ,对应意思就是 firmware、encryption、image
1
2
3
4
5
setattr("/runtime/tmpdevdata/image_sign" ,"get","cat /etc/config/image_sign");
$image_sign = query("/runtime/tmpdevdata/image_sign");
fwrite("a", $ShellPath, "encimg -d -i ".$fw_path." -s ".$image_sign." > /dev/console \n");
del("/runtime/tmpdevdata");
前两行代码是用于获取固件映像签名的命令,使用 setattr 函数将属性 /runtime/tmpdevdata/image_sign 设置为 cat /etc/config/image_sign ,再使用 query 函数从属性 /runtime/tmpdevdata/image_sign 中获取固件映像签名,并将其存储在变量 $image_sign 中。
即变量 $image_sign 将被设置为 wrgac43s_dlink.2015_dir822c1
第三行代码是用于执行固件映像解密操作,使用 fwrite 函数将命令字符串 encimg -d -i ".$fw_path." -s ".$image_sign." > /dev/console 写入文件 $ShellPath。后续会执行这个 shell
这个 encimg 程序位于 /usr/sbin
然后使用 readelf 命令可以知道该程序是32位大端MIPS架构
现在使用qemu用户模式进行模拟,并加上 encimg -d -i ".$fw_path." -s ".$image_sign. 等参数
.$fw_path. 就是加密度加密固件的路径,即 D-Link DIR-822-US 系列路由器 3.15B02 版本固件的路径
.$image_sign. 即 wrgac43s_dlink.2015_dir822c1
将 qemu-mips-static 与加密固件 DIR822C1_FW315WWb02.bin 复制到 squashfs-root 目录中
运行脚本
1
sudo chroot . ./qemu-mips-static ./usr/sbin/encimg -d -i ./DIR822C1_FW315WWb02.bin -s wrgac43s_dlink.2015_dir822c1
此时再用 binwalk 去查看 DIR822C1_FW315WWb02.bin ,不仅可以看到文件信息,还发现熵值也变了
提取解密后的固件
此时就可以使用 binwalk -Me 成功提取固件系统文件
参考链接:https://github.com/SecureNexusLab/IoTFirmwareAnalysisGuide
最后于 14小时前
被Arahat0编辑
,原因:
上传的附件: