首页
社区
课程
招聘
[翻译]DLINK路由器加密固件逆向分析
2020-5-19 11:53 10423

[翻译]DLINK路由器加密固件逆向分析

2020-5-19 11:53
10423

原文地址:https://payatu.com/blog/munawwar/solving-the-problem-of-encrypted-firmware
翻译:看雪翻译小组 八企鹅
校对:看雪翻译小组sudozhange

一个关于分析加密固件的案例

图片描述

简介

设备固件的安全性分析是物联网安全审核中非常关键的部分。获取固件是分析过程中的众多挑战之一,然而你可以通过很多方法来获取固件。获取固件后,对其进行分解以进行更深入的分析。但是,获取设备固件的最简单方法是从供应商更新服务器(通常是FTP服务器)下载该固件,他们在其中存储了不同版本的固件,而获取下一个版本的技术已编码在固件中。为防止出现这种情况,供应商已经以加密形式在服务器上存储固件,因此,即使您获取了固件,在进行任何进一步分析之前仍需要对其进行解密。

 

最近,我在ZDI博客上阅读了一篇非常有趣的文章,作者分享了不同的技术来解密固件,我强烈建议你去阅读该文章。在这篇文章中,我将带您详细分析DLINK路由器DIR-822 US变体的固件解密,我们将使用ZDI博客中介绍的技术,并详细研究设备如何处理解密以及对解密算法进行逆向分析。 所以,让我们开始吧。

固件对比技术

在本节中,我将为那些懒惰而又不愿阅读的人总结一下ZDI的帖子,如果您已阅读,则可以跳过本节。

 

让我们考虑一种情况,其中你拥有加密的固件版本,并且用于解密更新固件的算法在设备固件中。当你上传固件时,它将解密并开始正常的更新过程。但是,解密程序不是固件初始出厂版本的一部分,然后在后面的某个时间点,厂商考虑引入这种安全机制,因此他们在新的固件版本中加入新的加密/解密API函数。此版本被称为过渡版本。由于过渡版本未加密,因此我们可以对解密算法进行逆向分析并手动解密固件。这正是在这篇文章中我们要去实践的。

 

二进制对比是一种技术,您可以采用同一软件的不同版本的两个二进制文件并使用差异工具来了解程序新版本中引入的新功能。我们将使用kdiff3在过渡版本和之前的版本之间的文件系统进行区分,因为在过渡版本中将具有加密/解密程序,而先前的版本则没有。

产品的详细信息

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

产品ID: DIR-822-US
CPU架构: MIPS R3000
描述: 具有高增益天线的无线AC1200双频路由器
咨询链接: 咨询链接
下载: 下载链接

发行历史

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

发行时间 版本代号 文件名称
08/02/2020 3.15B02 DIR-822_REVC_FIRMWARE_v3.11B01_ICJG_WW_BETA.zip
03/12/2019 3.15B02 DIR-822_REVC_FIRMWARE_v3.15B02.zip
11/07/2019 3.13B01 DIR-822_REVC_FIRMWARE_v3.13B01.zip
10/05/2019 3.12B04 DIR-822_REVC_FIRMWARE_v3.12B04.zip
22/04/2019 3.11B01 DIR-822_REVC_FIRMWARE_v3.11B01.zip
17/09/2018 FW303WWb04_i4sa_middle DIR822C1_FW303WWb04_i4sa_middle.zip
17/09/2018 3.10B06 DIR-822_REVC_FIRMWARE_v3.10B06.zip
14/09/2017 3.01B02 DIR-822-US_REVC_FIRMWARE_v3.01B02.zip
08/06/2018 3.02B05 DIR-822_REVC_FIRMWARE_v3.02B05.zip
 

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/StartFirmwareDownload.php文件中,您将遇到以下代码段。

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

从上面的代码中,我们可以得出结论,使用命令
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参数,该参数指定用于加载依赖项的根目录的路径。 经常使用的另一种方法是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) = 3
stat("/home/payatu/test_1.bin", 0x7fffea90) = 0
write(1,0x7f689298,99)The file length of /project/dlink/AC1200/test_1.bin is 6865072

 = 99
read(3,0x7fffeb50,4) = 4
# mmap fd 3
mmap(NULL,6865072,PROT_WRITE,MAP_SHARED,3,0) = 0x7ef51000
munmap(0x7ef51000,6865072) = 0
# again truncate operation on fd 3
ftruncate(3,6865044,0,0,0,0) = 0
# good bye fd 3
close(3) = 0

逆向加密方法

您可以在您喜欢的反汇编程序/反编译器工具中加载encimg二进制文件,以进行更深入的分析。我偶然发现了一个有趣的函数main(0x401244),该方法解析参数,然后调用具有加密/解密所有核心功能的build(0x400d24)。此外,二进制文件还进行了加密相关导入,其中一些功能是_AES_set_encryptkey,_AES_set_decryptkey和_AES_cbcencrypt,这确认二进制文件正在使用AES加密算法,这意味着用于加密和解密文件的相同密钥。做一些简单研究,您可以了解到这些功能原型。以下是这些功能的简短说明。

// Same prototype for AES_set_encrypt_key
AES_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,社区版免费提供给任何人使用。如您所见,我使用固件审核程序进行了上面的大多数分析。 您可以在此链接上找到有关该产品的更多详细信息功能,并在同一页面上将您的反馈发送给我们。固件审核软件可用于:

  1. 查看熵图
  2. 探索Linux文件系统并下载所有内容(在我们的情况下为enimg二进制文件,PHP文件)
  3. build函数的反编译代码
  4. 以及点击获取更多信息

总结

我们看到了不同的方法来确定固件是否已加密,还看到了如何使用固件差异方法来找到要使用的解密方法,以及如何使用它并复制该方法到另一个固件。我们还讨论了解密方法打开的一些攻击面。 使用这种保护方案时,需要意识到这一点。

EXPLIoT.io

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

  1. EXPLIoT:物联网安全测试和开发框架
  2. Firmware Auditor:抢先的固件安全分析工具
  3. DIVA [不安全和易受攻击的应用程序]委员会
  4. NANO:一种简洁的,易于黑客使用的多用途,多协议的硬件工具
  5. ZigBee审核软件

这些是我们在物联网安全领域多年经验和专业知识的产物。 我们在这里可以帮助您改善安全状况。 有关更多信息,请访问https://expliot.io/或向我们发送电子邮件至info@expliot.io!

参考

  1. MINDSHARE: Dealing With Encrypted Router Firmware
  2. Qemu Userspace Emulation

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-5-19 11:55 被八企鹅编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回