在2019年,Mandiant的Red Team发现了Digi International的ConnectPort X2e设备中存在的一系列漏洞,该漏洞允许以特权用户身份远程执行代码。Mandian的研究专注于SolarCity 命名的ConnectPort X2e设备,该设备广泛用于住宅太阳能装置。
Mandiant与Digi International和SolarCity / Tesla合作,负责任地披露了研究漏洞成果,获得了以下两个CVE编号:
· 硬编码凭据(CVE-2020-9306,CVSS3.0:8.8)
· 特权执行(CVE-2020-12878,CVSS3.0:8.4)
技术细节可以在Digi International的3.2.30.6软件版本以及FireEye的Vulnerability Disclosures GitHub项目(FEYE-2020-0019和FEYE-2020-0020)中找到。
这个由两部分组成的系列博客将在更高层次上讨论我们的分析,探索获得对ConnectPort X2e设备的访问权的技术,并分享发现漏洞的技术细节。涉及的主题将包括物理设备检查,调试接口探测,芯片分析技术,固件分析,故障攻击和软件开发。
0x01 技术分析
设备概述
在深入探讨细节之前,我们将讨论ConnectPort X2e设备(在文章其他部分中称为X2e设备)。X2e设备是一个可编程网关,可连接到ZigBee设备并从中收集数据。它通常用作智能能源网关,以解释和发送来自住宅太阳能逆变器的能量读数。供应商通常会购买X2e设备并将其配置为读取客户的太阳能逆变器产生的功耗。图1概述了典型的住宅太阳能安装并突出了X2e的作用。
图1:典型的X2e住宅部署图
对于我们的研究,我们专注于SolarCity(现为Tesla)使用的X2e设备,以从住宅太阳能装置中检索数据。典型的设置将涉及SolarCity为客户提供网关,该网关将通过客户家庭网络上的以太网电缆连接到Internet。图2显示了我们测试过的SolarCity品牌的一种X2e设备。
图2:X2e设备
对于X2e设备,我们至少有两个要研究的接口:以太网接口和ZigBee无线电口。我们没有检查X2e和太阳能逆变器之间的ZigBee接口,并且该接口不会在本系列的第1部分或第2部分中介绍。
0x02 物理板分析
网络扫描
我们从网络角度评估X2e设备开始了我们的研究。通过使用nmap,我们发现该设备同时开放了SSH和HTTP/HTTPS,如图3所示。
图3:X2e的端口扫描结果
在远程访问这些服务时,我们注意到这两个服务都需要身份验证。我们还进行了暴力破解,但均未成功。此外,此设备的基础服务不容易受到漏洞载荷的攻击。由于没有多少基于网络的线索可循,因此我们将分析转移到硬件角度,以确定是否有可能进行任何本地攻击来获得对该设备的初始访问权限。
物理板分析
为了开始进行硬件分析,我们从设备上卸下了塑料外壳,并分析了各种集成电路(IC)组件,并搜索了潜在的调试接口。清点电路板上存在的组件(PCB)是了解器件的设计方式以及未来的预期中至关重要的一步。图4显示了映射出的组件以及一系列类似于典型3引脚通用异步发送/接收(UART)连接的引脚,这是嵌入式设备上的常见调试接口。
图4:X2e组件和可疑的引脚组
如果没有与X2e设备的远程连接,则UART是有吸引力的目标。UART通常提供SSH或Telnet之类的服务的等效功能,并具有在系统引导期间监视详细输出的附加好处。为了确定引脚组是否为UART接口,我们首先将引脚3通孔接头焊接到PCB上。通过将万用表的连续性测试与数字逻辑分析仪Saleae结合使用,很明显我们实际上是在处理UART接口。图5显示了连接到接头连接器的三个引脚(接地,TX,RX)。FTDI串行TTL-232转USB适配器连接到三根线的另一端,该适配器已连接到Linux虚拟机。
图5:连接到UART接口
除了正确识别UART引脚和UART至USB适配器外,我们还需要从接口读取/写入的软件以及波特率的知识。波特率有所不同,但通常遵循标准值,包括9600、14400、19200、38400、57600和115200。使用python模块pySerial,我们连接到USB适配器,并尝试了标准波特率,直到其中一种速率产生可读的ASCII输出(错误的波特率通常会产生不可读的输出),并确定X2e使用的波特率为115200。
引导X2e时,我们注意到BootROM,引导加载程序(它是常见的嵌入式引导加载程序Das U-Boot 2009.8)的输出,以及通过UART连接传输的Linux内核的输出,如图6所示。
图6:UART启动消息
U-Boot的许多配置允许物理连接的用户(使用诸如UART之类的接口)中断引导过程的能力。但是,此配置明确禁用了该功能,如图7所示。
图7:X2e上的不间断U-Boot引导程序
中断引导加载程序对于攻击者来说很有吸引力,因为传递给Linux操作系统的引导参数通常可以进行控制以控制其加载方式,例如引导进入单用户模式或以读写方式挂载文件系统。 对于X2e,UART连接已映射到Linux TTY,后者需要用户名和密码验证,如图8所示。
图8:通过UART对Linux的用户身份验证
没有任何能力来中断引导过程或凭据以对X2e进行身份验证,我们面临着另一个僵局。然后,我们将分析转移到获取存储在X2e非易失性存储中的固件上。
数据提取
在本节中,我们将介绍嵌入式设备上存在的非易失性存储器(闪存)的基础知识,以及从芯片中提取内容的过程。如上所述,盘点PCB上的组件是重要的第一步。图9显示了在数字显微镜下放大的PCB上存在的闪存芯片。
图9:Spansion flash的特写
图9中可见的标记很重要,因为它们使我们能够确定闪存的制造商和型号,这将有助于我们获得芯片的数据表。在我们的案例中,我们要处理的NAND是Spansion S34ML01G1,其数据表可以在此处找到。
https://datasheetspdf.com/datasheet/S34ML01G1.html
NAND概述
在讨论从NAND芯片获取固件之前,重要的是首先了解嵌入式设备通常会遵循的各种情况。
NAND与NOR相比:这些根本不同的技术各有其优点和缺点。NAND价格便宜,但遭受“坏块”或有时直接从工厂损坏的区域的可能性很高。因此,需要提供保护和考虑因素以能够对此进行保护。NAND的擦除和写入速度也要快得多,非常适合存储文件系统,内核和其他可能需要重置或更改的代码。NOR具有明显更快的读取时间,但在访问数据时不那么灵活,并且擦除和写入速度较低。NOR通常用于低级引导加载程序,硬编码固件blob和其他不希望频繁更改的区域。X2e使用 NAND闪存。
并行flash:这是指如何访问数据,并且通常在视觉上可识别。如果有大量的引脚,则flash很可能是并行的。串行NOR芯片的尺寸可能很小,通常需要八个或更少的引脚即可工作。常见的串行接口为串行外围设备接口(SPI)或集成电路间(I2C),而NAND的常见并行接口为开放式NAND闪存接口(ONFI2.0,ONFI3.0)。X2e是并行flash。
外形尺寸:另一种视觉上可识别的特征-外形尺寸是指芯片如何连接到PCB。有很长的选项列表在这里,但常见的表面贴装闪存包包括小外形封装(SOP),薄小外形封装(TOSP),或球栅阵列(BGA *)的变体。这里的主要区别是SOP和TOSP暴露引脚,而BGA则将引脚隐藏在封装下。X2e是 BGA63,也称为63引脚BGA封装。
受管与非受管闪存:由于NAND与NOR中提到的原因,该闪存更适用于NAND。如前所述,NAND需要帮助来管理数据的完整性。对于非托管NAND,IC会将闪存的部分(通常称为“备用”区域)保留给其他人来管理数据。通常将其实现为内核驱动程序或外部NAND控制器。托管NAND意味着IC封装包括控制器并透明地管理数据。这在嵌入式设备中极为常见,例如嵌入式MMC(eMMC)或通用闪存(UFS)。X2e使用 不受管理的闪存,并由PCB上的主微控制器控制。
在不了解基础知识的情况下,我们继续从PCB上物理移除了芯片。
芯片拆卸
物理取下芯片被认为是一种破坏性方法,但是可以在不损坏PCB或闪存芯片本身的情况下执行。当提出去除BGA封装时,两种最常见的去除技术是热空气或红外光(IR)。对于热空气和红外都存在商业解决方案,但是通过热空气去除存在更便宜的选择。我们选择在X2e上使用热空气。
为了最大程度地减少对PCB和flash的损坏,可以使用PCB加热器或热风枪
将整个PCB缓慢加热到恰好低于焊料熔点的温度。这将减少我们将热空气直接聚焦在闪存IC上所需的时间,并有助于减少整个过程中散发到PCB中的热量。
可以用来使附近的切屑不被损坏或丢失(由于气压)最小化的最后一个技巧是使用高耐热胶带,通常被称为Kapton胶带。图10显示了用Kapton胶带包裹的PCB,以保护附近的组件。
图10:PCB上的高耐热胶带
图11显示了将X2e PCB插入PCB加热器且热风枪悬挂在IC上方的示例设置。
图11:热风枪
在使用热空气加热IC及其周围区域的同时,我们轻轻地轻推flash以查看焊料是否已熔化。一旦芯片浮起,我们迅速将其取出并冷却约30秒钟。图12显示了ICflash已从PCB上移走,而焊料仍存在于BGA焊盘上。
图12:从X2e卸下的NAND
在将NAND插入编程器的读卡器之前,必须将剩余的焊料从闪存中清除。这可以通过使用烙铁,优质助焊剂和去焊芯来实现。异丙醇和牙刷一经清除,在清除残留的助焊剂残留物和清洁切屑方面非常有效。
在下一节中,我们将尝试使用多功能芯片编程器从NAND芯片中提取数据。
数据提取
有了清洁过的闪存芯片,我们现在可以探索读取原始内容的选项。存在商业取证设备,但是快速的eBay或AliExpress搜索将产生大量的通用芯片读取器。一种这样的设备XGecu Pro支持各种适配器和芯片组,并使用USB连接到Windows计算机。它还带有与XGecu Pro交互的软件,甚至可以自动检测flash。为了将Spansion NAND连接到XGecu Pro,我们还购买了翻盖式BGA63适配器。图13显示了插入翻盖式读取器的NAND,图14显示了连接到XGecu Pro设备的翻盖式适配器。
图13:BGA翻盖式适配器中的Spansion NAND
图14:连接到XGecu的NAND适配器
使用XGecu Pro软件,我们可以将闪存的全部内容读取到二进制文件中以进行进一步分析。由于这些不是商业解决方案,因此最好执行两次或三次读取,然后对提取内容进行差异化处理,以确保内容无误地被读取。
0x03 固件分析
固件解析
有了新的NAND转储文件,下一步就是解析所有相关的固件blob,配置或文件系统。启动此过程的必备工具是binwalk。binwalk在检测文件系统,引导加载程序和内核方面做得非常出色。此外,binwalk可以计算熵(检测打包或加密的数据)并识别程序集操作码。图15显示了针对NAND转储文件运行binwalk的部分输出。
图15:针对NAND转储的初始binwalk扫描数据
从输出中我们可以看到binwalk成功地确定了它所扫描出的U-Boot uImage标头,Linux内核映像以及十多个Journaling Flash File System版本2(JFFS2)文件系统。JFFS2是嵌入式设备中使用的通用文件系统。未排序的块映像文件系统(UBIFS)和SquashFS也很常见。
乍一看似乎是有希望的。但是,我们的NAND上实际上不存在JFFS2文件系统。另一个不完全正确的指示是十六进制偏移量,它们似乎不是干净的偏移量。由binwalk标识的项目的偏移量与NAND页面偏移量对齐是更为常见的,NAND页面偏移量是2048的倍数。
为了了解此处发生的情况,我们需要重新审视“ NAND概述”部分所述的原始NAND IC的特性。概括地说,原始NAND每页需要额外的字节,供更高级别的组件用来证明该页的有效性,通常以定义的“坏块”标记和每页(或子页)的纠错码( ECC)。ECC无需太深入探讨ECC基础知识,它为高级进程提供了检测页面上n个坏位并校正m个位的能力。
由于我们的目标不是对原始NAND执行取证,因此我们的近期目标是从NAND转储中删除ECC字节或其他与数据无关的字节。MCU最终是操纵原始NAND的系统,因此了解恩智浦iMX28系列MCU的MCU如何管理NAND对于实现这一点至关重要。
对我们来说幸运的是,安全社区已经探索了此过程,并且存在iMX解析库来操纵原始NAND转储并删除现有的无关数据。图16显示了在imx-nand-convert脚本的输出上重新运行binwalk的结果。
图16:固定NAND转储的binwalk扫描
这次,我们仅看到一个JFFS2文件系统,其偏移量为0x880000。使用binwalk的提取(-e)功能,我们现在可以获得U-Boot引导加载程序,Linux内核和JFFS2系统的解析版本。
我们需要克服的最后一个障碍是以一种允许我们探索内容的方式来安装提取的JFFS2文件系统。在Linux上,执行此操作最简单的方法是使用mtd,mtdblock和nandsim 内核模块。所述nandsim模块模拟给定NAND设备并使用该MTD和JFFS2子系统来解析和适当地管理。需要传递给nandsim模块的关键信息是ONFI芯片标识符,该标识符可以从NAND数据表获得,也可以通过使用通用读取器(如数据提取中使用的XGecu Pro)从IC请求ID来获得部分)。受支持的ID的列表也由mtd 维护。正确设置参数有些运气,可能需要编译自己的nandsim模块版本,该过程将不在本文中讨论。
图17显示了模拟正确的Spansion NAND并以Makefile目标的形式挂载JFFS2文件系统所需的步骤。
图17:挂载JFFS2文件系统的Makefile目标
通过运行make mount-jffs2,我们可以快速准备和挂载JFFS2文件系统,并像浏览文件系统一样浏览内容。
访问文件系统
在本文的最后一部分,我们将逐步分析JFFS2文件系统。请记住,我们的最终目标是获得一个可远程利用的漏洞,该漏洞将允许特权代码执行。考虑到这一点,某些感兴趣的领域正在运行守护程序/进程,系统启动逻辑以及用于侦听网络的服务的凭据。第一部分是查看/ etc / shadow文件,以查看是否有root用户和其他系统用户的密码哈希。快速检查此文件后,确定root用户没有密码哈希,这表明我们将无法使用密码身份验证进行身份验证。我们注意到存在另外两个密码哈希,分别是addpd和python用户,如图18所示。
图18:/ etc / shadow的连接
该addpd用户有一个默认密码,但是无法使用远程方式进行身份验证,而我们最终无法破解的python使用内部基于GPU的服务器用户的哈希值。
此外,我们对在系统引导或引导后启动的过程感兴趣。目录/ WEB / python /包含一个名为_x2e.zip的ZIP存档,其中包含200多个编译的Python脚本(PYC文件),这些脚本在系统启动时加载。使用反编译器uncompyle2,我们将这些文件解压缩以供查看。一个名称突出的文件是password_manager.pyc,该文件用于在成功启动后重置登录密码。该文件包含五个映射到python的硬编码和纯文本凭证系统用户。这些凭证可用于访问Web界面和SSH,如图19所示。Mandiant确认将不同的密码用于不同的版本和连接状态。Mandiant向SolarCity报告了此问题,并被分配了CVE编号CVE-2020-9306。
图19:password_manager.pyc中的硬编码凭证
使用正确的密码,我们终于能够连接到正在运行的X2e上的Web和SSH端口,但不幸的是,只有作为特权较低的python系统用户。尽管这是一个不错的开始,但它并不能满足我们的最终目标,即以特权用户的身份远程接管X2e。在本系列的第二部分中,我们将探索进一步攻击X2e的其他途径。
0x04 分析总结
在这个由两部分组成的博客系列的第1部分中,我们概述了X2e,我们最初的网络扫描,PCB检查技术,物理调试接口探测,拆卸读取技术和固件分析。使用这些方法,由于硬编码凭据漏洞(CVE-2020-9306),我们成功地以非管理用户的身份远程接入了X2e设备。在第二部分中,我们将以故障攻击的形式重新研究针对X2e的物理攻击,重新探索U-Boot引导加载程序,最后展示一种攻击,以特权用户的身份远程接管X2e设备。