-
-
[翻译]U-Boot NFS RCE漏洞(CVE-2019-14192)
-
发表于: 2019-10-14 21:37 6403
-
原文:https://blog.semmle.com/uboot-rce-nfs-vulnerability/
翻译:看雪翻译小组 - lipss
校对:看雪翻译小组 - Nxe
这篇文章是关于U-Boot引导加载程序中的13个远程执行代码漏洞的,我和我的同事Pavel Avgustinov和Kevin Backhouse发现了这些漏洞。当U-Boot配置为使用网络来获取下一阶段的启动资源时,可以触发这些漏洞。
请注意,该漏洞尚未通过https://gitlab.denx.de/u-boot/u-boot进行修补,并且我应U-Boot的主要托管人Tom Rini的要求将这些漏洞公开。有关更多信息,请查看下面的时间表。
MITER已针对这13个漏洞发布了以下CVE:CVE-2019-14192,CVE-2019-14193,CVE-2019-14194,CVE-2019-14195,CVE-2019-14196,CVE-2019-14197,CVE-2019 -14198,CVE-2019-14199,CVE-2019-14200,CVE-2019-14201,CVE-2019-14202,CVE-2019-14203和CVE-2019-14204
Das U-Boot(通常称为“通用引导加载程序”)是一种流行的主引导加载程序,广泛用于嵌入式设备中,以从不同来源获取数据并运行下一阶段的代码,通常(但不限于)Linux内核。IoT,Kindle和ARM ChromeOS设备通常使用它。
U-Boot支持从不同的文件分区格式(例如ext4),以及网络(TFTP和NFS)获取下一阶段的代码。请注意,U-boot支持验证启动,在其中检查获取的映像是否被篡改。这样可以减轻使用不安全的明文协议(例如TFTP和NFS)的风险。因此签名检查之前的任何漏洞都可能意味着设备越狱。
这些漏洞影响非常特定的U-Boot配置,其中指示U-Boot使用网络。这些漏洞中的一些存在于NFS解析代码中,而其他一些则存在于通用TCP / IP堆栈中。
此配置通常用于无盘IoT部署和快速开发过程中。
通过这些漏洞,同一网络(或控制恶意NFS服务器)中的攻击者可以在U-Boot驱动的设备上执行代码。由于此漏洞的性质,利用似乎并不十分复杂,尽管可以通过使用堆栈cookie,ASLR或其他运行时和编译时的内存保护机制来提高其挑战性。
通过源代码审查在2个非常相似的事件中发现了第一个漏洞,我们使用了Semmle的LGTM.com和QL来查找其他漏洞。它是普通的memcpy
溢出,攻击者控制的大小来自网络数据包,没有任何验证。
该问题存在于nfs_readlink_reply
解析来自网络的nfs答复的函数中。它解析4个字节,并且无需进一步验证,就在两个不同位置中将它们用作memcpy
的长度。
目标缓冲区nfs_path
是一个全局缓冲区,最多可容纳2048个字节。
以下查询为我们提供了9个列表,以便手动进行跟踪。查询背后的想法是从任何辅助函数(例如ntohl()
/ ntohs()
...)到memcpy
的size参数来执行数据流分析。
我们检查了结果,虽然有些数据在从源到接收器的数据流之间进行了大小检查,但发现有些数据是可利用的。此外,我们通过源代码审查发现了其他一些变体。
nfs_lookup_reply
函数再次解析来自网络的nfs答复时存在此问题。它解析4个字节,并在两个不同位置中将它们用作memcpy
的长度。
进行长度检查以确保它不大于分配的缓冲区。不幸的是,可以用负值绕过此检查,这将在以后导致较大的缓冲区溢出。
目标缓冲区filefh
是一个全局缓冲区,最多可容纳64个字节。
nfs_read_reply
读取文件并将其存储到另一种介质(闪存或物理存储器)中以供以后处理时,该函数中存在此问题。同样,数据和长度由攻击者完全控制,并且从未验证。
关注store_block
函数的物理内存部分,它尝试使用特定于arch的函数map_physmem
保留一些内存,最终调用phys_to_virt
。正如您在x86实现中所看到的那样,在保留物理内存时,它显然忽略了长度,并为您提供了原始指针,而没有检查周围区域是否为其他目的保留。
其后在store_block
中有一个攻击者控制的源和长度的memcpy
缓冲区溢出。
flash_write
代码路径中也可能存在类似的问题。
函数net_process_received_packet
在未经验证的情况下使用ip->udp_len
会导致整数下溢。其后,此字段将用于通过net_set_udp_handler
(DNS,dhcp,...)设置的memcpy
atnc_input_packet
和所有udp数据包处理函数中。
请注意,我们并未审计为不同目的(DNS,DHCP等)设置的所有潜在udp处理程序。但是,我们确实对nfs_handler
进行了审计,如下所述。
这是上述漏洞的代码审查变体。在此,当解析很大的ip->udp_len
参数的udp数据包时会发生整数下溢,随后又调用nfs_handler
。在此函数中,同样没有对长度的验证,我们将调用辅助函数,例如nfs_readlink_reply
。该函数盲目使用长度而不进行验证,从而导致基于堆栈的缓冲区溢出。
我们确定了5个不同的易受攻击的函数,它们遵循相同的代码模式,从而导致基于堆栈的缓冲区溢出。除了nfs_readlink_reply
之外,还有:
这与以前的漏洞非常相似。开发人员试图在复制来自套接字的数据时执行大小检查,以保持谨慎。当他们检查以防止缓冲区溢出时,他们没有检查源缓冲区中是否有足够的数据,从而导致潜在的读取越界访问冲突。
攻击者可以向NFS数据包提供读取请求和发送给套接字的较小数据包请求。
为了缓解这些漏洞,只有两种选择:
此漏洞报告受披露政策的约束,在此处可见https://lgtm.com/security/#disclosure_policy。