欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

MacOS再次出现漏洞,号称牢不可破的系统也有弱点

来源:本站整理 作者:佚名 时间:2018-11-05 TAG: 我要投稿

为了方便表达,本文将采用第一人称的方式叙述。
本文讲述了我在苹果的macOS系统内核中发现的几个堆栈和缓冲区溢出漏洞,苹果官方将这几个漏洞归类为内核中的远程代码执行漏洞,因此这些漏洞的威胁级别非常高。攻击者可以通过这些漏洞远程入侵Mac,也可以在通过物理的方式访问计算机时,仅需要以访客身份登录(无需密码),就可以通过这些漏洞从而获取权限并控制计算机。
这些漏洞基本都存在于NFS协议中,就是用来将网络驱动安装至Mac的文件系统时使用的,类似于NAS。
漏洞相关内容
苹果公司在2018年7月9日发布的MacOS 10.13.6版本更新中修复了这些漏洞。但是当时他们要求我们先不要公布这些漏洞,因为他们需要再做一些调查,看看其他平台上有没有类似的问题或者是否需要解决。当然,现在我们可以敞开说了。
NFS这个东西,现在的使用范围已经非常广,特别是在一些大型企业中,它主要用于共享驱动或联网设备的主目录等内容。当然,也可以在家庭设备中使用,通常会用作媒体服务器。
在macos中,安装NFS不需要特殊的权限,因此任何级别的用户都可以触发这些漏洞,甚至是不需要密码的访客账户。此外许多计算机(尤其是企业环境中的)会配置为在启动时自动挂载NFS共享。
这意味着这些漏洞至少存在两个攻击媒介:
1.可能被用于在使用NFS文件管理器的企业中快速传播病毒。
想要做到这一点,攻击者只需要在其文件管理器上安装具备恶意代码的NFS服务器软件即可,或者通过将恶意文件管理器放在网络上去拦截NFS流量来达成目的。
2.用于提权。
比如,有些人会使用Guest身份登录,然后发出一系列命令连接到NFS服务器(可能存在于网络的任何位置),就可能在计算机上获取内核级别的访问权限。
苹果公司为这五个漏洞分配了CVE分别是:CVE-2018-4259,CVE-2018-4286,CVE-2018-4287,CVE-2018-4288和CVE-2018-4291。我在2018年5月21日发给苹果的漏洞报告中,分别在源码中列出了14条不确定的点。但由于苹果最近才发布了更新,所以我也没有来得及完成对全部源代码的审核。因此,为避免意外泄露任何可能未修复的错误,本文中我只谈及其中两个已经得到验证和修复的漏洞。
漏洞复现
我编写了一个PoC去验证漏洞的可用性,可以使用0覆盖4096个字节的堆内存从而导致内核崩溃。我做了一个简短的视频来证明这一点。
4096是一个随机选择,事实上我可以随意修改来发送尽可能多的数据,任何大于128字节的数都会触发缓冲区溢出,我也能够完全控制写入的字节值。因此,尽管这些动作只破坏了内核,但是实际上是可以通过这些缓冲区溢出来实现远程代码执行以及本地提权的操作。
在我第一次发现这个漏洞时,几乎不敢想象我会为了PoC去自己编写NFS服务器。但是在我学了一些NFS相关知识以及了解到如何使用rpcgen之后,我就发现其实想要实现也非常简单。用来验证这个漏洞的PoC,仅包含46行C语言以及63行 RPC语言代码。当然,这些源代码会在苹果官方完成全部修复之后再放出。
漏洞详解
在我写的PoC中,这两个漏洞都需要通过这一行看似无害的代码来实现:
nfsm_chain_get_fh(error, &nmrep, nfsvers, fh);
这行代码的作用是读取NFS服务器发送回Mac的回复消息(nmrep)中的文件句柄(fh)。这个文件句柄是NFS共享的文件或目录中的不透明标识符。NFSv3中的文件句柄最多64个字节,NFSv4中最多128个字节,XNU中的fhandle_t类型则有足够的空间容纳128字节的文件句柄,但是他们却忽略了去检查nfsm_chain_get_fh宏中的缓冲区溢出情况:
/* get the size of and data for a file handle in an mbuf chain */
#define nfsm_chain_get_fh(E, NMC, VERS, FHP) \
  do { \
    if ((VERS) != NFS_VER2) \
      nfsm_chain_get_32((E), (NMC), (FHP)->fh_len); \
    else \
      (FHP)->fh_len = NFSX_V2FH;\
    nfsm_chain_get_opaque((E), (NMC), (uint32_t)(FHP)->fh_len, (FHP)->fh_data);\
    if (E) \
      (FHP)->fh_len = 0;\
  } while (0)
由于宏命令的大量使用,想理解这段代码可能有些难,但它的实际作用却非常简单:它能够从消息中读取一个32为无符号整数到(FHP)->fh_len,然后读取该字节数,从消息直接进入(FHP)->fh_data。由于没有边界检查,因此攻击者可以选择任何字节序列覆盖任意数量的内核堆。被覆盖的文件句柄在内存中的nfs_socket.c:1401中分配。
这个PoC中,第二个bug是nfsm_chain_get_opaque中的整数溢出:
/* copy the next consecutive bytes of opaque data from an mbuf chain */
#define nfsm_chain_get_opaque(E, NMC, LEN, PTR) \
  do { \
    uint32_t rndlen; \
    if (E) break; \
    rndlen = nfsm_rndup(LEN); \
    if ((NMC)->nmc_left >= rndlen) { \
      u_char *__tmpptr = (u_char*)(NMC)->nmc_ptr; \
      (NMC)->nmc_left -= rndlen; \
      (NMC)->nmc_ptr += rndlen; \
      bcopy(__tmpptr, (PTR), (LEN)); \
    } else { \
      (E) = nfsm_chain_get_opaque_f((NMC), (LEN), (u_char*)(PTR)); \
    } \
  } while (0)
这段代码使用bfsn_rndup将LEN移动至4的下一个倍数处。但它在调用bcopy时会使用LEN的原始值。如果其初值为0xFFFFFFFF,则nfsm_rndup中将出现加法溢出,renlen的值为0,这意味着能够与(NMC)->nmc_left比较成功,并且使用0xFFFFFFFF作为size参数调用bcopy。这便会导致内核崩溃,因此它被用作拒绝服务攻击。
使用QL查找错误
QL的一大优势是能够找到已知错误的变种。今年早些时候,我的同事Jonas Jensen在苹果的NFS启动中发现了两个漏洞:CVE-2018-4136和CVE-2018-4160。我们当时也发布了一篇关于这些漏洞的文章,主要就是针对对bcopy的调用,这个调用可能存在为负的用户控制的大小参数。最简单的方法就是查找用户控制源缓冲区中对bcopy的调用。这很有趣,因为它们可以将用户的数据复制到内核中。

[1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载