查看原文
其他

DLINK路由器加密固件逆向分析

八企鹅 看雪学院 2021-03-06



本文为看雪论坛精选文章

看雪论坛作者ID:八企鹅






简介


设备固件的安全性分析是物联网安全审核中非常关键的部分。获取固件是分析过程中的众多挑战之一,然而你可以通过很多方法来获取固件。获取固件后,对其进行分解以进行更深入的分析。

但是,获取设备固件的最简单方法是从供应商更新服务器(通常是FTP服务器)下载该固件,他们在其中存储了不同版本的固件,而获取下一个版本的技术已编码在固件中。

为防止出现这种情况,供应商已经以加密形式在服务器上存储固件,因此,即使获取了固件,在进一步分析之前仍需要对其进行解密。

在这篇文章中,我将详细分析 DLINK 路由器 DIR-822 US 变体的固件解密,并详细研究设备如何处理解密,并对解密算法进行逆向分析。





固件对比技术


让我们考虑一种情况,其中你拥有加密的固件版本,并且用于解密更新固件的算法在设备固件中。当你上传固件时,它将解密并开始正常的更新过程。

但是,解密程序不是固件初始出厂版本的一部分,然后在后面的某个时间点,厂商考虑引入这种安全机制,因此他们在新的固件版本中加入新的加密/解密API 函数。

此版本被称为过渡版本。由于过渡版本未加密,因此我们可以对解密算法进行逆向分析并手动解密固件。这正是在这篇文章中我们要去实践的。
 
二进制对比是一种技术,您可以采用同一软件的不同版本的两个二进制文件并使用差异工具来了解程序新版本中引入的新功能。我们将使用 kdiff 3 在过渡版本和之前的版本之间的文件系统进行区分,因为在过渡版本中将具有加密/解密程序,而先前的版本则没有。




产品的详细信息


在深入研究之前,让我们看一下设备的一些详细信息。







发行历史


简略浏览路由器固件的发行历史,下表显示了发布日期以及 FTP 服务器上的版本 ID 和文件名。


2018 年 9 月17日发布的 FW303WWb04 _i4sa_middle 固件似乎有些奇怪。我解压固件文件并在每个固件二进制文件上执行 binwalk 语句,观察每个文件的结果,发现到一个有趣的事情,即所有固件在FW303WWb04_i4sa_middle 以及之前的版本中至少都有一个使用 lzma  压缩的 squashfs 文件系统。

在 FW303WWb04_i4sa_middle 版本之后的任何固件都没有签名匹配。在进一步分析 DIR822C1_FW303WWb04_i4sa_middle.zip 文件中找到的发行说明 pdf 时,如下所示,这证实了我的猜想。
 
 
这个更新的固件是一个过渡版本,其中引入了加密/解密,因为您可以看到同一日期有两个固件更新,并且在发行说明中还提到固件 v3.10 必须从过渡版本 v303WWb04middle 升级。看来我们开了一个好头。




可视化方法


如果在某些情况下,发行说明中未提及固件保护,则可以使用熵计算方法来确定固件是否已加密。简而言之,熵是对随机性的一种度量,它的值在0到1之间,值越大表示随机性越好。接近1的值被认为是高熵,反之亦然。压缩或加密的数据具有较高的熵值。

二进制图像的熵分布将为我们提供二进制文件增量偏移的熵值。此信息将帮助您猜测二进制文件的哪个部分被加密/压缩以及哪个是代码。让我们看一下两个不同二进制版本的熵分布,一个是过渡加密的FW303WWb04_i4sa_middle 版本,另一个是加密的 3.15B02 版本。让我们来看看它们之间的区别。
 

 
如果您注意到图中的差异,则图 B 的熵几乎恒定在 0.9 以上,这意味着很有可能在固件的不同部分对其进行了加密。

在图 C 中,初始部分的熵很低,然后一直很高,然后又下降,然后再次上升,这种波动表明它是代码和加密/压缩数据的混合。
 
对于未加密的固件,您经常会看到这种模式,该固件最初具有波动性,随后的部分中具有较高的熵数据。这可能意味着二进制文件的初始部分中存在代码,该代码会在设备启动时动态解压缩(来自后面的部分)代码。
 
注意:加密和压缩在这里都被归咎于高熵,因为没有确切的方法可以根据熵值来判断其中哪一个是造成随机性的原因。
 
接下来,我们应该尝试找出新版本中进行了哪些更改,并尝试破解该算法。





文件系统分析


现在我们知道了过渡的版本,让我们通过在版本3.02B05和FW303WWb04_i4sa_middle 之间进行文件系统的区分来找出新版本中引入了哪些更改。

我们将为此使用 kdiff3 。我们应该在文件名中查找包含诸如“固件”,“更新”,“升级”,“下载”或这些关键字的组合关键字。




动态分析加密的二进制


在进行文件差异搜索期间,您将可以找到许多与固件更新功能相关的文件,但问题的实质是位于第111行的 /etc/templates/hnap/StartFirmwar Download. php 文件中,您将遇到以下代码段。

// fw encimgsetattr("/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");

从上面的代码中,我们可以得出结论,使用命令:

encimg -d -i <fw_path> -s <image_sign>

执行的名为 encimg 的二进制文件。

接下来,我搜索 encimg 二进制文件在文件系统中的位置,它位于路径 /usr/sbin/encimg 中,其他未知变量是 fw_path,我假设它是固件路径,另一个变量是 image_sign,我们可以追溯该值 该变量的变量是从 /etc/config/image_sign 中读取的,还有一个 -d 参数尚不清楚。

 
让我们做一些动态分析,以进一步解密该命令。
 
运行一个简单的文件 file 命令表明它是 ELF 32 位 MIPS MSB 的可执行文件。现在,我们可以将 MIPS 架构的 qemu 用户空间仿真器用于 MIPS 架构来运行此二进制文件。去到固件的 squashfs-root 目录下,然后运行以下命令。

$ qemu-mips -L <rooth path of file system> ./usr/sbin/encimg
Usage: encimg {OPTIONS} -h : show this message. -v : Verbose mode. -i {input image file} : input image file. -o {output image file} : output image file. -e : encode file. -d : decode file.   -s                      : signature.$ qemu-mips -L <rooth path of file system> ./usr/sbin/encimg

注意:在上面的命令中,我们为 qemu-mips 提供 -L 参数,该参数指定用于加载依赖项的根目录的路径。经常使用的另一种方法是 Linux chroot 。

从上面的帮助用法消息中,很明显,这是用于解密固件的二进制文件,-s 参数称为签名,但是我认为它用于将解密密钥作为从文件 /etc/config/image_sign 中读取的参数。

该文件包含字符串值 _wrgac43s_dlink.2015dir822c1,我认为它是解密密钥。另一个参数 -i 是输入文件,它将是新接收到的加密固件文件。现在,让我们尝试使用 qemu 仿真器解密此固件。

qemu-mips -L . ./usr/sbin/encimg -d -i <path to encrypted firmware> -s wrgac43s_dlink.2015_dir822c1

Qemu 用户空间仿真器还具有另一个有趣且非常重要的功能,它可以逆转称为strace 的立场,该立场可以执行二进制文件进行的系统调用日志记录。

您可以通过为 qemu 提供 -starce 参数来启用它,它将打印二进制文件进行的所有系统调用,我在上述二进制文件上进行了尝试,并提取了一些有趣的日志,如下所示:

# Aahh.... a crypto library been loaded by the binary, it# hints that it is using some sort of encryption algorithm possiblity AES# or some symentic encryption algorithm as we have seen there already# a password we provide to the binary.open("/lib/libcrypto.so.0.9.8", O_RDONLY) = 3.........# opening the file (return fd 3)open("/home/payatu/test_1.bin", O_RDWR) = 3stat("/home/payatu/test_1.bin", 0x7fffea90) = 0write(1,0x7f689298,99)The file length of /project/dlink/AC1200/test_1.bin is 6865072
= 99read(3,0x7fffeb50,4) = 4# mmap fd 3mmap(NULL,6865072,PROT_WRITE,MAP_SHARED,3,0) = 0x7ef51000munmap(0x7ef51000,6865072) = 0# again truncate operation on fd 3ftruncate(3,6865044,0,0,0,0) = 0# good bye fd 3close(3) = 0





逆向加密方法


您可以在您喜欢的反汇编程序/反编译器工具中加载 encimg 二进制文件,以进行更深入的分析。我偶然发现了一个有趣的函数 main(0x401244),该方法解析参数,然后调用具有加密/解密所有核心功能的build(0x400d24)。


此外,二进制文件还进行了加密相关导入,其中一些功能是_AES_set_encryptkey,_AES_set_decryptkey 和 _AES_cbcencrypt ,这确认二进制文件正在使用 AES 加密算法,这意味着用于加密和解密文件的相同密钥。做一些简单研究,您可以了解到这些功能原型。以下是这些功能的简短说明。 


// Same prototype for AES_set_encrypt_keyAES_set_decrypt_key ( // user input key const unsigned char *userKey, // size of key const int bits, // encryption key struct which will be used by // encryption function AES_KEY *key)
AES_cbc_encrypt ( // input buffer const unsigned char *in, // output buffer unsigned char *out, // buffer length size_t length, // key struct return by previous function const AES_KEY *key, // initializatin vector unsigned char *ivec, // is encryption or decryption const int enc)


让我们看一下 bulid 函数的反编译代码。

 

 

从上面的代码可以看出,我们可以说二进制文件通过 mmap 函数映射到内存中。


然后通过基于参数调用 AES_set_encrypt_key / AES_set_decrypt_key来设置 AES_KEY 数据结构,并使用该结构通过 AES_cbc_encrypt 加密/解密有效负载,然后使用 munmap 函数调用将数据写回到文件中。这没有什么难度!





结果


一旦我们解密了固件。我们再来看一下解密后的固件的熵。

 

 

它看起来与我们之前看到的未加密固件非常相似。






枚举攻击面




1. 由于我们正在将二进制文件上传到操作系统服务(固件更新服务)以处理该文件。我们可以在文件解析中找到使用过的解密算法的 bugs ,并通过某种内存损坏问题来破坏服务流程,从而使我们可以访问系统。


2. 我们可以使用诸如固件 mod-kit 之类的固件修补工具来更改固件文件并重新打包,并使用相同的加密二进制文件对其进行加密并上传文件以进行更新。


如果没有完整性检查方法,则修补的固件将更新而不会出现任何问题。尽管使用了加密,但是恶意固件更新仍然是一个问题。固件签名机制用于克服这种攻击。


注意:由于项目时间和范围的限制,我尚未测试上述攻击。但是如果我是攻击者,我会尝试上述的攻击方法。





固件审核软件


使用十种不同的工具进行分析可能既耗时又容易出错,这反映了我们的日常工作流程,我们创建了一个工具来自动执行繁琐的固件分析工作,该产品称为Firmware Auditor ,社区版免费提供给任何人使用。


如您所见,我使用固件审核程序进行了上面的大多数分析。您可以在此链接上(https://expliot.io/pages/firmware-auditor)找到有关该产品的更多详细信息功能,并在同一页面上将您的反馈发送给我们。固件审核软件可用于:


1. 查看熵图


2. 探索 Linux 文件系统并下载所有内容(在我们的情况下为 enimg 二进制文件, PHP 文件)


3. build 函数的反编译代码


4. 以及点击获取更多信息





总结


我们看到了不同的方法来确定固件是否已加密,还看到了如何使用固件差异方法来找到要使用的解密方法,以及如何使用它并复制该方法到另一个固件。


我们还讨论了解密方法打开的一些攻击面。使用这种保护方案时,需要意识到这一点。





EXPLIoT.io


在 EXPLIoT.io,我们构建了用于物联网(IoT)基础架构和产品的安全测试的工具。


1. EXPLIoT:物联网安全测试和开发框架

2. Firmware Auditor:抢先的固件安全分析工具

3. DIVA【不安全和易受攻击的应用程序】委员会

4. NANO:一种简洁的,易于黑客使用的多用途,多协议的硬件工具

5. ZigBee 审核软件





参考


1. MINDSHARE : Dealing With Encrypted Router Firmware
https://www.thezdi.com/blog/2020/2/6/mindshare-dealing-with-encrypted-router-firmware

2. Qemu Userspace Emulation
https://www.qemu.org/docs/master/user/main.html





- End -





看雪ID:八企鹅

https://bbs.pediy.com/user-890713.htm



  *本文由看雪论坛 八企鹅 翻译, sudozhange 校对,来源自payuta's blog 转载请注明来自看雪社区。




推荐文章++++

*  读书笔记——典型FTP软件的模糊测试和漏洞利用

*  2020网鼎杯青龙组_re_signal

*  新手向总结:IDA动态调试So的一些坑

*  .NET 恶意代码分析入门

*  一款最简单的关于动态注册的APP分析

*  java函数转Native化的一些实践









公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



“阅读原文”一起来充电吧!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存