虚假的 RCE vs 真实的 RCE

吐槽一下最近 外网爆的 macOS Finder RCE。

前言

前两天看 HackerNews 的时候发现一条新闻:

news

而这个漏洞的出处更加劲爆,原标题直接就是: SSD Advisory – macOS Finder RCE。吓得我赶紧点进去看看,发现漏洞原因竟然很简单: 在 macOS 中,点击 .netloc 后缀的文件可以执行指定命令。

netloc

netloc 文件本身是一个快捷方式文件,从浏览器中点击网址拖拽到桌面或者 Finder 文件夹中就可以自动生成这么一个文件,通常文件内容是:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>URL</key>
    <string>https://evilpan.com/</string>
  </dict>
</plist>

点击该文件后会直接使用默认浏览器打开 URL 指定的网址。而上文中的 PoC,则是将网址改为file://地址,比如:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>URL</key>
    <string>FiLe:///System/Applications/Calculator.app</string>
  </dict>
</plist>

这样点击该 .netloc 文件就会打开计算器。苹果对于 netloc 的 URL 过滤了 file:// 协议,但是仅对字符串进行了过滤,因此上面将 file 改成 FiLe 就可以简单绕过了。

另一个 ”RCE“

如果这个也叫做 RCE,那我也来分享一个 RCE,将下面的文件保存成 poc.fileloc:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>URL</key>
  <string>file:///System/Applications/Calculator.app</string>
</dict>
</plist>

甚至都不需要大小写绕过 file 的协议,直接双击打开:

震惊,又一个 RCE

当然,效果和上面的“漏洞”一样,只能打开任意本地程序,不能指定参数,所以从实际上来说,并没有什么卵用。除了 .fileloc 后缀,.url 后缀也有同样效果。

Quarantine

那么,为什么这么一个 Feature,会被上面的安全研究员说成是 RCE 呢?个人猜测除了 PR/KPI 的压力,还有一个重要原因是在 MacOS 中下载的可执行文件通常有更加严格的安全校验,即 Gatekeeper/Quarantine。

如果可执行文件包含com.apple.quarantine属性,那么在运行前会进行一系列检查:

  1. Gatekeeper 校验目标的签名 (codesign)
  2. Gatekeeper notarization check
  3. Gatekeeper 恶意代码扫描
  4. Quarantine 提示用户该应用通过互联网下载,是否要执行

看到前面的 RCE,有人应该就问了,何必要这种奇怪的后缀,直接保存成可执行文件不是更方便?可惜,这种常见的可执行文件 (.app,machO 等) 在下载后都会被加上 Quarantine 属性,用户点击会弹出二次确认警告,因此实用价值就大打折扣了。

虽然可执行文件不能点击运行,脚本应该可以吧?可惜实际上点击 .sh/.bash/.applescript 等文件默认是用 XCode 打开的。不过,还有一个特殊的文件格式可以直接点击运行,而且不需要加chmod +x权限,它就是 .terminal 文件。

一个简单的 PoC 示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CommandString</key>
	<string>echo "Hello"</string>
	<key>ProfileCurrentVersion</key>
	<string>2.06000000001</string>
  <key>RunCommandAsShell</key>
  <false/>
  <key>name</key>
  <string>poc</string>
  <key>type</key>
  <string>Window Settings</string>
</dict>
</plist>

直接保存成 poc.terminal ,点击即可运行任意命令,而且不止可以弹计算器,还可以控制任意执行命令的参数。当然,苹果也有意识到这个问题,所以从浏览器下载的 .terminal 文件也是会被加上 Quarantine 属性的。

但是相比于.app等可执行文件,.terminal 文件有一个独特的优势: 因为该文件是 plist 格式,因此没有 codesign 签名检查,所以一旦我们可以绕过 Quarantine 检查,就可以实现真正的 RCE。

真 · macOS RCE

网上下载的可执行文件会被加上 Quarantine 属性,这句话中我们可以提出一个问题: 这个属性是谁加的?答案很简单: 浏览器。也很容易验证,因为在命令行中使用 wget/curl 下载的可执行文件是没有 Quarantine 属性的。

既然如此,我们可以再提一个问题,如果是在 APP 中下载呢?比如 Telegram、WhatsApp、PC 微信、QQ、钉钉等等。所以一个新的攻击面呼之欲出: 我们可以对于一些可以从 APP 内下载并打开文件的行为中构造一个 RCE,比如以 WhatsApp 为例(已经修复):

WhatsApp RCE

大部分桌面应用的开发者都不会注意这种安全特性,因此很容易在需要的目标中构造这种钓鱼场景。对于一些带有自动下载文件功能的 APP(比如 Telegram),甚至可以做到一键 RCE。

当然,Telegram 也已经修复了该漏洞 :)

总结

本文介绍了最近讨论比较多的一个 RCE,并介绍了一个类似的 macOS RCE(fileloc 后缀执行文件),这其实是个陈年老问题了,编号为 CVE-2009-2811,苹果一直也懒得修,毕竟只能弹计算器装逼,执行不了什么有意义的代码,所以我更愿意称之为 Feature。在此基础上介绍一种在桌面应用中使用 .terminal 后缀绕过 Quarantine 和 Gatekeeper 实现真正 RCE 的例子。

希望各国安全研究员还是要多珍惜自己的羽毛,少在安全会议上灌水和发布些虚假的 RCE 预警吧。Peace。

参考资料

Quarantine nights - Exploring File Quarantine handling in macOS Apps / @Metnёw