CVE-2020-25860 - RAUC嵌入式固件更新框架中发现重大漏洞

JFrog的安全研究团队(前身为Vdoo)不断研究领先的嵌入式设备及其供应链。作为这项研究的一部分,我们发现了CVE-2020-25860,这是一个潜在的严重漏洞,在鲁棒自动更新控制器(RAUC的开源框架固件更新。JFrog负责任地披露了这个漏洞,并与供应商Pengutronix密切合作,以验证该漏洞的修复。企鹅网已经通知了客户,他们还发布了一份安全咨询在GitHub官方存储库上。此漏洞存在于包含该补丁的1.5版本之前的所有RAUC版本中。
此漏洞为“检查时间-使用时间”(cwe - 367)问题,允许攻击者访问固件更新文件,覆盖它之后,它已被验证(但在安装完成之前),从而允许安装任意固件更新,绕过加密签名检查机制。
此漏洞的影响
与供应链漏洞一样,很难准确估计有多少设备受到了影响。考虑到这是一个开源工具,并且它可以被许多与供应商没有关系的不同公司使用,这个估计甚至更加复杂。因此,Pengutronix可以根据他们的客户证明其流行程度,他们估计在该领域有多达10万台设备,但我们相信数字要高得多,因为RAUC提供了大多数设备所需的核心功能。我们已经看到RAUC在工业、智能建筑和医疗等多个垂直领域的几种不同设备中使用。正如我们将在下面详细说明的那样,这个漏洞还需要某些条件才能被利用,特别是远程利用。我们已经在至少一个现实世界的设备中看到了这些条件。然而,目前,据我们所知,这个漏洞并没有在现场被利用,因此,没有对任何使用RAUC的人造成任何具体的隐私侵犯或安全威胁。
RAUC的背景
RAUC是一个始于2015年的项目,它被开发成一个轻量级工具,可以为基于linux的嵌入式设备执行故障安全映像更新。
RAUC允许嵌入式Linux开发人员在他们的嵌入式设备上集成一个健壮的更新客户端,同时避免编写任何样板更新代码。RAUC框架支持许多常见的引导加载程序(U-Boot、grub等)和开箱即用的存储技术(ext4、uifs等),因此试图尽可能接近嵌入式设备固件更新的“全套”解决方案。
RAUC的主要特性是安全性(原子的、故障安全的更新操作)、安全性(加密签名检查)和可定制性(在安装过程中添加用户钩子)。
技术深潜
RAUC使用捆绑包文件作为保存新固件的存档。我们发现,在固件升级过程中,该文件可以被攻击者替换(在初始验证步骤之后),这样就会安装恶意固件,有效地允许攻击者控制系统。
运行时安装bundle.raucbRAUC运行以下内部函数:
- Check_bundle() -使用openssl库调用验证bundle
- Mount_bundle() -使用“mount”shell调用挂载bundle
完成这些步骤后,将提取挂载的bundle并覆盖当前固件。
关键的问题是,一旦check_bundle()完成运行,bundle文件就会关闭,并且不会以任何方式保留经过验证的数据。
当mount_bundle()开始运行时,mount shell调用会导致重新读取bundle数据:
gboolean mount_bundle(RaucBundle *bundle, GError **error){…g_message("将bundle '%s'挂载到'%s'", bundle->path, mount_point);Res = r_mount_loop(bundle->path, mount_point, bundle->size,…)gboolean r_mount_full(const gchar*源,const gchar*挂载点,const gchar*类型,goffset大小,const gchar* extra_options, GError **error){…如果(getuid () ! = 0) {g_ptr_array_add (args, g_strdup(“sudo”));g_ptr_array_add (args, g_strdup(”——非交互式“));} g_ptr_array_add(args, g_strdup("mount"));…g_ptr_array_add (args, g_strdup(源));… sproc = r_subprocess_newv(args, G_SUBPROCESS_FLAGS_NONE, &ierror); ...
因此,攻击者可以在调用check_bundle()和mount_bundle()之间切换bundle文件。这使得攻击者可以部署任意恶意固件,从而在设备上提供root权限:

图1:攻击流,当进程到达mount_bundle()时,攻击者可以替换bundle文件,这样RAUC将挂载一个未经授权的bundle
赢得竞争条件(在check/mount bundle调用之间替换bundle文件)的机会非常高,因为两个操作之间有不可忽略的代码量,包括shell调用(“mount”命令),这是一个非常慢的操作。
观察到的远程攻击场景
尽管在大多数情况下,我们认为该漏洞可以作为本地特权升级加以利用,但我们已经观察到,在利用一组默认硬编码凭据的情况下,该漏洞可以被远程攻击者利用。
目标设备使用一组默认硬编码凭证(用户名和密码设置为“admin”),首次登录时不需要更改。
这些凭证可以很容易地被访问设备固件的攻击者提取,或者通过简单的暴力攻击猜测。
看看设备的攻击面:
- 目标设备公开了一个经过身份验证的CGI端点
upload.cgi这允许任意文件上传到硬编码的文件路径-/ tmp / rauc / bundle.raucb - 目标设备公开了一个经过身份验证的CGI端点
install.cgi哪个运行了硬编码shell命令-安装/tmp/rauc/bundle.raucb - 在两个CGI端点之间没有适当的锁定机制
在这种情况下,攻击者可以远程接管设备,只需调用:
upload.cgi使用正确签名的固件install.cgi(很快)upload.cgi带有恶意固件

本地攻击场景和PoC
假设本地用户具有调用RAUC的特权(例如,通过只允许使用RAUC命令的sudo配置),但没有签署RAUC包所需的私钥,那么利用就很简单了:
复制一个正确签名的固件到某个路径,例如:。/ bundle.raucb
调用RAUC -安装/bundle.raucb
迅速取代。/ bundle.raucb带有恶意固件
如果本地用户不能调用RAUC命令(假设调用RAUC命令的特权用户使用攻击者可以写入的路径),也可以利用这种情况。
我们已经开发了一个概念验证,利用了这个确切的场景:
- PoC接受要替换的bundle文件的完整路径
- PoC等待另一个用户运行
rauc安装通过监视默认目录(/ mnt / rauc),在验证步骤之后但在挂载步骤之前创建 - 一旦验证结束(创建目录),PoC就会用任意输入覆盖bundle文件
在真实的攻击场景中,攻击包文件可以移动到正确签名的包文件上(这比在正确的位置写入新文件要快)。
作为设备供应商,我如何知道我的设备是否受到此漏洞的影响?
您可以通过在设备上运行此命令来检查您的RAUC版本是否容易受到攻击
rauc——版本
如果报告的版本低于1.5,那么您的设备包含易受攻击的代码。
在实践中,只有当本地或远程攻击者有可能在安装时修改bundle文件时,设备才容易受到攻击。
例如,在以下场景中可能发生这种情况:
- 非特权用户可以调用
rauc命令,可以通过sudo机制、setuid机制或任何其他专有机制。中的下面一行/etc/sudoers文件将允许" vdoo "用户以root身份调用RAUC:vdoo ALL=(root) /usr/bin/rauc rauc安装在任何时候使用非特权用户可以修改的包路径调用。例如:安装/tmp/mybundle.raucb
由于/tmp默认情况下是全球可写的,因此通常任何用户都可以修改其下的文件。
作为资产所有者,我如何知道我部署的任何设备是否存在漏洞?
不幸的是,似乎很难判断这个漏洞是否存在,更重要的是,它只适用于网络工具,或者不实际查看设备代码。
话虽如此,如果您的设备供应商确实为设备提供了软件材料清单(SBOM),请查看是否使用了RAUC,如果使用了RAUC,那么理论上您很可能易受攻击(除非版本明确列出为1.5),因为存在易受攻击的代码。
但这并不意味着该漏洞是可利用的(请参阅上面的更多详细信息)。如果设备供应商没有提供软件物料清单(SBOM),我们认为您应该要求它提供一份,以及他们对此漏洞适用性的明确回应。
如何升级RAUC?
使用此链接获取有关将RAUC 1.5版集成到基于Yocto/OE、ptxdist和buildrog -的现有项目中的示例
https://github.com/rauc/rauc-1.5-integration/
您也可以按照以下说明编译最新版本的RAUC:
https://github.com/RAUC/RAUC#building-from-sources
如果无法升级RAUC,如何降低风险?
如上所述,这是一个典型的Time-of-Check-Time-of-Use漏洞,其中攻击利用涉及检查资源和资源使用情况的非原子操作。在本例中,检查是签名检查,使用是挂载/升级操作。
通过确保安装是原子式的,并且从安全路径进行,可以减轻攻击。
在运行之前rauc安装,将bundle文件从全局可写位置复制到安全位置(仅限root可写位置),并从该路径运行安装。使用存在的安全位置作为锁定机制。这将确保没有非特权用户(本地或远程)可以干预安装过程。
这可以通过下面的shell脚本来实现:
#假设固件上传到/tmp/uploads/bundle.bin #假设/data/fw_upgrade只能由root用户写,如果[!]-e /data/fw_upgrade/bundle.bin];cp /tmp/uploads/bundle.bin /data/fw_upgrade/bundle.bin /usr/bin/rauc install /data/fw_upgrade/bundle.bin rm /data/fw_upgrade/bundle.bin
请注意,在使用像Yocto这样的构建系统时,更改安装脚本可能不会比切换到固定的RAUC版本容易得多。有关如何升级的详细信息,请参阅下文。有关更多缓解详细信息,请参考官方咨询.
鸣谢
我们要感谢Pengutronix团队有效和迅速地处理了这个安全问题,以及他们的专业沟通行为。我们高度重视他们的行为,他们应该在负责任的披露过程中为所有供应商树立榜样。
问题吗?想法吗?如有任何疑问,请致电research@m.si-fil.com与我们联系安全漏洞.
除了发现并负责任地披露漏洞作为我们日常活动的一部分之外,JFrog安全研究团队还通过授权组织通过自动安全分析发现漏洞来增强软件安全性。有关JFrog DevOps平台安全特性的更多信息和更新-点击这里.
