SonicWall固件深度解析 - SWI固件解密
在Bishop Fox,我们花费大量时间研究客户使用的网络设备。这些通常是高权限设备,保护公共互联网与敏感内部网络之间的边界。我们的研究包括漏洞研究和高级指纹识别技术,这些技术使我们能够详细了解客户的攻击面。获取未加密和未混淆的固件是几乎所有此类研究的先决条件。
这是三部分系列中的第一篇,详细介绍了我们在解密和分析SonicWall防火墙方面的工作。我们从SWI固件解密的演练开始,因为这种文件格式尚未被先前的研究覆盖。第二篇文章将利用我们改进的指纹识别能力,基于面向互联网的暴露情况调查SonicWall防火墙安全的当前状态。系列的第三部分将提供SIG固件的深度技术分析,超越先前的研究,详细说明我们如何解密最普遍的SonicOS文件格式并使文件系统安装程序可供未来研究使用。
SonicOS文件格式
首先,让我们看看SonicWall用于分发SonicOS的文件格式,这是其防火墙设备底层的操作系统。下表总结了根据SonicWall支持站点上可下载映像为每个防火墙模型提供的不同文件格式。
防火墙型号 | 客户层级 | 固件文件格式 |
---|---|---|
SOHO | 小型企业/家庭办公室 | SIG |
TZ | 中小型企业 | SIG |
NSa | 中大型企业 | SIG |
Supermassive | 大型分布式企业(传统) | SIG |
NSsp | 大型分布式企业 | SIG, SWI |
NSv | 云和混合虚拟环境 | SIG, SWI, OVA, VHD, QCOW2 |
先前的研究主要关注NSv OVA(VMware)固件映像,因为它们在成本和技术复杂性方面是最易访问的(以及VHD/Hyper-V和QCOW2/KVM映像)。当前的研究,包括我们自己的研究,一直在更仔细地研究SIG格式,因为它具有普遍适用性,但直到最近,这种格式对逆向工程提出了重大障碍。
SWI格式的独特之处在于它仅用于NSsp 15700设备和NSv虚拟机更新。此外,只有SonicOS版本6.5.4.4到7.0.1以这种格式发布。这种有限使用的模式表明,SonicWall可能开发了这种格式作为为虚拟机映像提供额外安全性的首次尝试。第一个NSv版本是6.5.4.4,虚拟机本质上必须包括解密任何加密组件的能力,因此SonicWall希望模糊该过程以帮助保护其他固件免受逆向工程的影响是可以理解的。随着SonicOSX在版本7.0.0的发布,SonicWall改进了用于SIG固件映像的加密过程,并且从版本7.1.0开始,NSv映像也采用了这种格式。我们假设SWI格式在那个时候被废弃了。
在本文的其余部分,我们将研究SWI固件,并详细说明我们遵循的逆向工程其加密方案的过程。
SWI文件头
我们通过查看十六进制转储开始了对SWI格式的分析。这揭示了一个大的文本头,后跟字符串“Salted__”和一堆看起来随机的数据。“Salted__”字符串强烈暗示主体是使用OpenSSL的自定义格式加密的。该格式在“Salted__”字符串之后立即有一个8字节的盐,该盐与密码结合,并传递给密钥派生函数以派生密钥和初始化向量(IV)。
图1 - SWI头的十六进制转储
我们检查了二进制数据之前的文本头,发现它由三个部分组成。第一行包括字符串“SWI_HEADER”、一个平台(“PLATFORM=vmware”)和一个版本(VERSION=3)。下一行是256字节的base64编码的随机数据。最后一部分是PGP签名块。第一和最后部分的目的对我们来说是清楚的,但我们只能尝试猜测随机base64的目的。
我们最初希望这个base64数据可能是密码,但我们尝试使用这个与各种OpenSSL参数组合从未导致成功解密。尽管如此,鉴于这似乎是随机数据,在头中没有其他明确的目的,我们继续逆向工程,假设这个随机头数据可能参与获取加密密码的过程。
逆向工程获取密码
一开始,我们遇到了一个鸡生蛋蛋生鸡的问题。为了逆向工程固件解密过程,我们需要包含解密代码的未加密固件。这个问题的解决方案由Praetorian的sonicwall-nsv-decrypter和博客文章提供,他们逐步介绍了解密和root SonicWall NSv虚拟机的过程。使用Praetorian的工具,我们能够获得解密固件并访问SonicWall NSv 6.5.4.4-44v-21-1519设备上的shell。
使用此访问权限,我们搜索了任何可能负责处理SWI文件的代码。递归grep ‘.swi’返回了相对较少的结果,当我们查看web-front二进制文件时,函数components/imagemgmt.readSWIHeader()引起了我们的注意,因为顾名思义,它负责解析SWI头。
从readSWIHeader()回溯函数调用,我们找到了components/imagemgmt.processImageFile()。此函数使用OpenSSL解密文件,使用从utils/vaultutil.DecryptPgpKey()调用获得的密码。
DecryptPgpKey是一个辅助函数,它与运行在http://127.0.0.1:8200的HashiCorp Vault API接口。我们发现此函数使用硬编码的API令牌进行身份验证,并将请求发送到/v1/transit/decrypt/swikey。根据Vault文档,此端点将使用名为“swikey”的密钥解密base64编码的数据。进一步阅读文档,我们注意到如果配置为可导出,我们可以导出私钥,并且应该可以修改密钥配置以启用可导出标志。
使用我们的root shell,我们能够通过以下命令恢复私钥:
|
|
密钥配置表明它是一个“rsa-2048”密钥。根据文档,这意味着数据将使用OAEP填充算法与SHA-256作为哈希函数和掩码生成函数进行解密。使用此信息,我们决定尝试使用swidec密钥解密来自SWI文件头的base64字符串。这产生了128字节的随机数据,但解密没有导致任何填充错误,这强烈暗示我们正在正确解密数据。最后,我们使用此解密数据作为解密文件主体的密码。这产生了一个tar文件,其中包含存储为压缩tar文件的根文件系统的明文版本,以及一个GPG签名。
我们将此过程转换为以下Python脚本:
|
|
结论
使用我们的脚本,我们能够解密许多NSv和NSsp固件映像变体进行分析。这种访问,结合我们通过类似过程解密的其他映像格式的访问,使我们能够为SonicWall设备构建详细的指纹识别能力。请继续关注本系列的第二部分,该部分将讨论我们的后续研究,利用从解密固件中获得的知识分析数十万个暴露在互联网上的SonicWall设备。