虚假的 RCE vs 真实的 RCE
前言
前两天看 HackerNews 的时候发现一条新闻:
而这个漏洞的出处更加劲爆,原标题直接就是: SSD Advisory – macOS Finder RCE[1]。吓得我赶紧点进去看看,发现漏洞原因竟然很简单: 在 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 的协议,直接双击打开:
当然,效果和上面的“漏洞”一样,只能打开任意本地程序,不能指定参数,所以从实际上来说,并没有什么卵用。除了 .fileloc
后缀,.url
后缀也有同样效果。
Quarantine
那么,为什么这么一个 Feature,会被上面的安全研究员说成是 RCE 呢?个人猜测除了 PR/KPI 的压力,还有一个重要原因是在 MacOS 中下载的可执行文件通常有更加严格的安全校验,即 Quarantine/Gatekeeper。
如果可执行文件包含com.apple.quarantine
属性,那么在运行前会进行一系列检查:
1.Gatekeeper 校验目标的签名 (codesign)2.Gatekeeper notarization check3.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 为例(已经修复):
大部分桌面应用的开发者都不会注意这种安全特性,因此很容易在需要的目标中构造这种钓鱼场景。对于一些带有自动下载文件功能的 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[2]
引用链接
[1]
SSD Advisory – macOS Finder RCE: https://ssd-disclosure.com/ssd-advisory-macos-finder-rce/[2]
Quarantine nights - Exploring File Quarantine handling in macOS Apps / @Metnёw: https://objectivebythesea.com/v3/talks/OBTS_v3_vMetnew.pdf