当前位置: 首页 > 科技观察

如何在物联网设备中挖掘复杂的恶意软件

时间:2023-03-15 09:19:55 科技观察

在本文中,我们将为读者详细介绍如何在物联网设备中挖掘复杂的恶意软件。这篇文章的动机之一是鼓励对这个话题感兴趣的其他研究人员加入进来,分享他们的想法和知识,并构建更多的安全工具来更好地保护我们的智能设备。研究背景智能手表、智能家居设备甚至智能汽车……随着越来越多的连接设备加入物联网生态系统,确保其安全性的重要性不言而喻。众所周知,如今已经成为我们生活中不可或缺的一部分的智能设备,在面对各种网络攻击时,并不是很安全。事实上,针对物联网设备的恶意软件已经存在了十多年。其中,Hydra是第一个已知的自动路由器恶意软件,于2008年作为开源工具公开。然而,Hydra只是一个开源路由器恶意软件原型。Hydra面世后不久,安全专家就在野外发现了针对网络设备的恶意软件。从那时起,不同的僵尸网络家族出现并广泛传播,包括Mirai、Hajime和Gafgyt家族。除了上面提到的恶意软件,物联网设备使用的通信协议也暴露出很多漏洞,例如Zigbee协议。该设备传播恶意软件,就像计算机蠕虫一样。在这项研究中,我们专注于挖掘针对物联网设备的低级复杂攻击。具体来说,我们将特别关注物联网设备的固件,以发现后门植入、篡改启动过程以及恶意篡改固件的其他部分。接下来,我们先介绍一下物联网设备固件的结构,以便更好地理解各个组成部分。物联网固件结构无论物联网设备的CPU架构如何,启动过程都包括以下几个阶段:引导加载程序、内核和文件系统(如下图所示)。当物联网设备启动时,板载SoC(片上系统)上的ROM中的代码首先将控制权转移到引导加载程序,然后引导加载程序加载内核,进而挂载根文件系统。引导加载程序、内核和文件系统也构成了典型物联网固件的三个主要组件。IoT设备的启动过程IoT设备中使用了许多不同的CPU架构。因此,需要深入了解这些架构及其指令集,以便分析和理解固件的不同组件。在物联网设备中,最常见的CPU架构包括:ARMMIPSPowerPCSPARC可能的攻击场景了解固件结构后,我们可以检查攻击者如何在部署难以检测的隐形攻击时利用这些组件。引导加载程序是获得系统控制权的第一个组件。因此,针对引导加载程序的攻击为攻击者执行恶意任务提供了极好的机会。这也意味着攻击可以在重新启动后持续存在。除此之外,攻击者还可以操纵内核模块。事实上,大多数物联网设备都使用Linux内核。正如开发人员可以轻松地从Linux内核中自定义和选择他们需要的任何内容一样,设法访问和操纵设备固件的攻击者可以添加或编辑内核模块。接下来,让我们检查文件系统。事实上,许多常用的文件系统都可以用于物联网设备。这些文件系统通常很容易被攻击者利用。攻击者可以从固件中提取、解压缩和挂载原始文件系统,添加恶意模块,然后使用通用实用程序再次压缩它。例如,SquashFS是Linux的压缩文件系统,在物联网供应商中非常流行。使用Linux实用程序“squashfs”和“unsquashfs”,我们可以非常轻松地挂载或解压缩SquashFS文件系统。本研究的挑战获取固件在实践中,有多种获取固件的方法。在进行调查时,有时我们希望固件来自具有完全相同规格的设备。同时,我们也希望通过某种特定的方式将其部署到设备上。例如,您怀疑用于更新固件的网络存在安全问题,并且您希望调查更新后的固件以验证其完整性,因为固件在供应商的服务器和设备之间传输时可能被篡改。在另一个示例场景中,您的设备可能是从第三方供应商处购买的,并且怀疑固件可能已被篡改。除此之外,还有大量物联网设备的制造商根本没有实施任何获取固件的方法,甚至懒得更新它。换句话说,这些固件从设备出厂之日起开始,终生不变。在这种情况下,获取这些固件的最可靠方法是从设备本身中提取它们。这里的主要挑战是该过程不仅需要相关的特定领域知识,还需要使用嵌入式系统的专业硬件/软件经验。如果想要挖掘针对物联网设备的复杂攻击,这种方法也缺乏可扩展性。在获取物联网固件的各种方式中,最简单的是从设备制造商的网站下载固件。但是,并非所有制造商都在其网站上发布其固件。通常,大多数物联网设备只能通过设备的物理接口或用于管理设备的特定软件应用程序(例如移动应用程序)进行更新。从供应商网站下载固件时的一个常见问题是您可能无法找到特定设备型号的旧版本固件。我们也不要忘记,在许多情况下,发布的固件二进制文件是加密的,它们只能由设备上安装的旧固件模块解密。了解固件根据维基百科,“固件是专门的计算机软件,旨在提供对设备特定硬件的低级控制。固件既可以为更复杂的设备软件提供标准化的操作环境(增加硬件独立性),也可以作为用于不太复杂设备的完整操作系统,提供所有控制、监视和数据处理功能。”虽然固件的主要组成部分几乎都是一样的,但固件并没有标准的架构。固件的主要组件通常是引导加载程序、内核模块和文件系统。但是,在固件二进制文件中还可以找到许多其他组件,例如设备树、数字证书和其他特定于设备的资源和组件。从制造商的网站获得固件二进制文件后,我们可以继续分析和反汇编它们。由于固件的特殊性,其分析过程不仅非常具有挑战性,而且非常繁琐。要获取有关这些挑战及其解决方案的更多信息,请参阅物联网固件分析部分。查找固件中的可疑元素提取固件的组件后,您就可以开始查找可疑模块、代码片段或恶意篡改组件。首先,我们可以根据一组YARA规则扫描文件系统内容,这些规则可以基于已知的物联网恶意软件或启发式规则。此外,我们可以使用防病毒扫描程序来扫描解压文件系统的内容。同时,也可以在文件系统中寻找启动脚本。这些脚本通常包含每次系统启动时加载的模块列表。恶意模块的地址很可能被插入到这些脚本中。在这里,我们可以利用Firmwalker工具扫描解压缩的文件系统以查找可能存在漏洞的文件。Firmwalker的功能(https://craigsmith.net/Firmwalker/)另一个需要研究的领域是引导加载程序组件,尽管这更具挑战性。IoT设备中常用的bootloader有很多,其中以UBoot最为常见。事实上,由于UBoot具有高度的可定制性,因此很难判断编译后的代码是否被篡改过。此外,在不常见或自定义引导加载程序中查找恶意修改将更加乏味。物联网固件分析目前有很多开源和闭源的工具可以帮助我们分析固件。然而,在实践中,我们最好结合使用经验丰富的固件分析师推荐的工具和技术。接下来,让我们从功能最丰富的固件分析工具Binwalk入手。Binwalk可用于扫描固件二进制文件并查找已知模式和签名。该工具不仅集合了物联网设备的各种bootloader和文件系统的签名,还提供了常用的加密和压缩算法的签名,以及相应的解压和解码例程。除此之外,Binwalk还能够提取固件二进制文件中的组件。下面的屏幕截图显示了示例固件二进制文件的Binwalk扫描输出:Binwalk工具扫描结果在上图中,Binwalk找到并打印了标头、引导加载程序、Linux内核和文件系统。此外,还输出了从头信息中提取的元数据和组件本身的相关详细信息,例如每个组件的类型和大小、CRC校验和、重要地址、CPU架构、图像名称等。现在,我们可以继续使用Binwalk提取上述组件,或者根据Binwalk找到的起始偏移量手动计算其大小,提取相关组件。解压固件组件后,我们可以继续对文件系统进行解压、解压甚至挂载,查看文件系统的内容。当然,我们也可以在反汇编器中查看bootloader的代码,或者通过调试器进行调试。然而,固件分析并不总是直截了当的。事实上,固件种类繁多,了解其结构和提取组件往往相当繁琐。接下来,让我们仔细看看另一个示例固件,并尝试了解它的结构。1.Binwalkfirmware.binBinwalk扫描结果没有任何显示。这意味着Binwalk没有找到任何已知的签名。Binwalk扫描结果在这种情况下,我们发现简单的Binwalk扫描不是很有帮助。但是请注意,我们还可以使用其他工具和技术来深入了解固件的结构。2.文件firmware.bin让我们使用Linux系统的文件工具来检查这个固件的二进制文件。文件实用程序的输出文件实用程序将文件类型显示为Targa图像数据。查看二进制文件的标头,并通过Google搜索Targa图像数据签名,这显然是误报。这种误报的原因是固件二进制文件的第一个字节0x01010000的内容与Targa图像数据的签名匹配,请参见上面的屏幕截图。3.Binwalk-Efirmware.bin现在,让我们开始使用Binwalk工具的另一个功能:检查固件二进制文件的熵。当使用“-E”命令选项运行Binwalk时,它会输出固件二进制文件的熵图,以及一些额外的细节,例如熵增加和减少开始的偏移量。熵相关细节熵图熵值接近1的内容被压缩,而熵值较低的内容未压缩和未加密。从上面的截图可以看出,从偏移量55296(0xD800)开始,熵值进入高值区。此外,还有另一个可用于可视化二进制文件的工具:binvis.io。它允许我们通过两个并排的窗格检查和可视化固件文件的内容。文件的不同部分根据熵值以不同的颜色显示。binvis.io创建的固件的可视化4.Binwalk-Afirmware.bin此外,Binwalk可以扫描二进制文件以获取常见可执行操作码的签名。ThefirstfunctionprologuefoundinthefileThelastfunctionprologuefoundinthefile从上面的截图我们可以看出,操作码签名检查结果其实非常有用!首先,我们可以通过这个来判断固件属于ARM设备。其次,如果我们考虑第一个和最后一个函数序言签名的偏移量,我们可以得出结论,这些偏移量指向固件二进制文件中代码所在的部分。从截图中我们还可以看到,最后一个函数位于地址0xD600处,也就是熵上升部分之前的0x200字节处。由此,我们可以做出有根据的猜测:这个偏移量可能指向引导加载程序代码结束的位置,同时也指向压缩内核模块开始的位置。5.hexdump-Chexdump-Cfirmware.bin|grep-C4-e"^\*$"现在我们知道了固件文件中一些组件的大概边界,我们可以查看实际内容来确认这些边界的具体偏移量.如果我们通过hexdump遍历固件文件并查找仅包含星号“*”的代码行,我们可以找到编译器为每个固件组件添加的填充字节。固件二进制文件的内容固件二进制文件其他部分的内容使用Hexdump实用程序的输出,结合之前的发现,我们能够确认包含ARM代码的固件二进制文件部分。我们之前怀疑这段代码属于引导加载程序。6.字符串--radix=xfirmware.bin接下来,让我们从固件中提取ASCII字符串和相关的偏移量。在固件二进制文件中找到的最后一个ASCII字符串从上面的截图来看,其中一些是与模块入口点相关的字符串。这些字符串可以帮助我们更好地理解相关代码的性质。在下面的截图中,我们可以从固件二进制文件的开头看到一些有趣的字符串。例如,库名称“MctlApplet.cpp”可用于查找来自同一开发人员的其他二进制文件或包。拥有来自同一供应商的其他固件映像有助于更好地理解这些二进制文件的结构。从同一个屏幕截图中,另一个引起我们注意的字符串是“NotBootingfromsoftloader”,它可能用于指示进程的状态或此模块的性质。同时,包含“Assert()”的字符串也可能隐含着代码的不同信息。使用Asserts函数是固件开发中非常常见的做法,因为它可以帮助开发人员在开发和生产阶段对代码进行调试和故障排除。在固件二进制文件中发现的第一个ASCII字符串7.IDA-parmfirmware.bin到目前为止,我们已经从这个固件二进制文件中收集到了很多有价值的信息,这些信息乍一看似乎相当难以理解。现在,让我们使用IDA检查代码。由于这个二进制文件不是带有标准头的ELF文件,我们需要明确告诉IDA使用ARM指令集来反汇编代码。IDA中函数部分的反汇编视图上面来自IDA的屏幕截图显示了如何使用在前面的分析步骤中找到的字符串来帮助查找对内核模块入口点的调用。8.dd现在,我们可以继续提取固件二进制代码部分,我们分析发现该部分属于引导加载程序模块。9、Qemu从固件二进制文件中提取出所有模块(文件系统内容、内核模块等组件)后,我们就可以使用Qemu来运行这些二进制文件,甚至可以模拟运行与我们自己机器不同架构的文件,并与之进行交互.总结如今,物联网设备的数量与日俱增。物联网设备无处不在,从工业控制系统、智能城市和汽车到消费设备,如手机、网络设备、个人助理、智能手表和各种智能家电。物联网设备起源于已经存在多年的嵌入式系统。由于这些设备的性质,嵌入式设备软件的制造和开发始终具有与通用计算机系统不同的优先级。这些优先级是由设备本身有限和特定的能力、底层硬件的有限能力和容量以及开发的代码无法进行后续更改和修改决定的。同时,物联网设备与传统的嵌入式系统有很大不同。如今,大多数物联网设备都在具有与通用计算机系统类似功能的硬件上运行。随着物联网设备变得越来越普遍,它们现在正在访问和控制我们生活和日常互动的许多方面。物联网设备现在有可能为攻击者提供前所未有的入侵机会。这不仅凸显了物联网设备安全的重要性,也凸显了围绕该课题开展研究的现实意义。不过,好消息是,已经有许多工具和技术可用于协助安全研究人员进行该领域当前和未来的研究。掌握物联网设备的架构,学习这些设备所说的语言,决心和毅力是进入这个研究领域所需要的。