一、前言
在最近几篇文章中,我们讨论了macOS中存在的一些漏洞或者缺陷,使得恶意代码能够执行各种恶意操作,比如绕过SIP、允许安装内核扩展、转储keychain数据以及其他操作。然而,这些漏洞利用技术都需要恶意代码已经(通过某种方式)获取目标系统上的初始代码执行权限。换句话说,这些技术都属于本地攻击范畴,通常会在攻击活动的第二阶段所使用。
今天我们将讨论恶意软件一直在使用的一种远程攻击技术,这种技术可以用来获取已打全补丁macOS系统的初始访问权限,属于第一阶段攻击技术。如果与之前介绍的各种第二阶段攻击技术结合起来,就可以通过优雅又有害的方法来攻击macOS系统。
注意:
虽然这种远程攻击方法仍需要一些用户交互操作,然而的确能够搞定具有安全意识的macOS目标用户。换句话说,大家需要小心这种攻击方法。
8月30日,来自DarkMatter LLC的Taha Karim在HITB会议上做了“The Trails of WINDSHIFT APT”主题演讲,他总结道:
WINDSHIFT APT是最近发现的一个隐蔽的网络间谍组织,专门攻击为政府工作的人员。这个攻击组织拥有专门的高级渔叉式钓鱼基础设施,可以为钓鱼邮件以及SMS攻击提供服务,在侦察阶段不间断地跟踪目标人员,也可以通过假冒全球及本地的服务商平台,在凭据收集阶段欺骗目标用户。
WINDSHIFT APT组织之所以与其他APT组织有所不同,原因在于他们会根据间谍和监控目的,只关注特定的个体,并且由于他们惯用的攻击手段,我们很难对其追踪溯源。WINDSHIFT APT组织很少使用恶意软件攻击目标,Dark Matter LLC发现了该攻击组织发起的几次攻击活动,并且分析了相关的macOS恶意软件。最后,WINDSHIFT APT有独特的macOS感染技巧,滥用macOS的原生功能自动将恶意软件投递到目标。
演讲中比较有趣的一个内容就是攻击者会滥用这种攻击方法,成功远程感染中东某政府的Mac系统。
注意:
本文的并不是简单地重述Taha的演讲内容,而是在此基础上进一步深入分析这款恶意软件的感染机制:
1、讨论macOS上的一些相关细节;
2、提供某些PoC代码片段;
3、讨论这种远程攻击方式的缓解措施。
二、Document Handler及URL Scheme
简而言之,WINDSHIFT APT组织滥用了自定义的URL Scheme来远程感染macOS目标。尽管该过程中需要用户交互,但成本很小,并且一定程度上可以受攻击者“控制”。此外,这种攻击方法已经有成功的攻击案例(攻击中东的政府目标),表明需要用户交互并不是一种无法突破的“屏障”。
在macOS上,应用程序可以“声明”自己能够支持(或者“处理”)各种文档类型以及/或者自定义的URL Scheme。想象一下,某个应用可能会说“如果有用户尝试打开foo
文档类型或者bar
这种URL Scheme,我可以处理这种场景”。大家肯定在macOS上碰到过这种场景。比如,当我们双击一个.pdf
文档,Preview.app
就会被启动来处理该文档。或者在浏览器中,我们点击了指向Mac App Store中的一个链接,App Store.app
就会启动来处理这个请求。
不幸的是,Apple对Document Handler(文档处理程序)以及自定义URL Scheme的实现(或者“注册”)方法决定了攻击者可以滥用这种功能。
从操作系统的角度来看,尽管文档处理程序以及URL Scheme略有不同,但本质上是一样(因此实现方法也非常相似)。
首先我们来快速看一下Document Handler,前阶段我刚研究过这方面内容,写过一篇介绍性文章。
在之前的文章中,我分析了Mac File Opener
这款广告软件(adware),该软件滥用了自定义的文档处理程序来实现隐蔽的持久化目标。简而言之,这款恶意软件“声明”自己能够支持超过200种类型的文件,一旦用户打开其中一种文件,恶意软件就会被操作系统自动启动来处理(理论上是显示)文档。非常耐心的持久化方法。
注意:如果已经有一个程序注册了一种文件类型(比如
.html
等),(据我所知)这种绑定关系无法被篡改。
当然这里第一个问题是,Mac File Opener
广告软件(或者其他应用)如何“声明”自己能够支持哪些文件(因此在用户访问此类文件时会被调用)。第二个问题是,操作系统如何处理并注册这种信息?我推荐大家阅读这篇文章,其中详细回答了这两个问题,但是这里我们也会简单地做一下总结。
那么应用程序如何告诉操作系统自己能够处理哪类文件?答案就在于程序的Info.plist
文件总。前面提到过,Mac File Opener
支持超过200种文件类型,我们可以导出它的Info.plist
文件:
在“原始的”plist中,这个信息存放在一个数组中(CFBundleDocumentTypes
键)。根据Apple的说法:
CFBundleDocumentTypes
(iOS及OS X上的数组)包含一个字典数组,将一个或多个文档类型与具体应用关联起来。每个字典都为类型定义(type-definition)字典,包含用来定义文档的具体键(key)。
举个例子,.7z
(7Zip)文件类型的Mac File Opener
详细信息如下所示,请注意其中的CFBundleTypeExtensions
这个key,对应的值为该广告软件声明的可以处理的文件扩展名:
$ cat "Mac File Opener.app/Contents/Info.plist"
<?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>BuildMachineOSBuild</key>
<string>14F27</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>7z</string>
</array>
<key>CFBundleTypeName</key>
<string>DocumentType</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>????</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>NSDocumentClass</key>
<string>Document</string>
</dict>
为了回答第二个问题,我们需要确定macOS如何处理这些文件的“注册”请求。在“Click File, App Opens”这篇文章中提到,这是一个自动化过程,一旦应用保存到本地磁盘上就会执行该操作。简单总结下,大致步骤如下:
1、应用(或者恶意软件)下载或者保存到本地文件系统中;
2、该过程会导致一个XPC
消息发送到launch services daemon(lsd
);
3、lsd
守护进程解析该应用,将应用的“document handlers”信息提取并保存到一个数据库中。
# fs_usage -w -f filesystem | grep Info.plist
open /Users/user/Desktop/Mac File Opener.app/Contents/Info.plist lsd.16457
fstat64 F=4 lsd.16457
read F=4 B=0x18a97 lsd.16457
# /usr/libexec/lsd
...
(lldb) po $rsi
<LSDatabase 0x7fe66183e600>{ path = '/var/folders/np/85lyz_4545d5lz8wvy04xvlm0000gn/0//com.apple.LaunchServices-134501.csstore' }
我们可以利用lsregister
(具体路径为/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/
)来转储lsd
的数据库。当使用-dump
标志调用时,lsregister
可以显示指定了“document handler”的所有应用,lsd
会自动注册这些“document handler”。比如,我们可以看到其中包含Mac File Opener
及其注册的文档(文件类型,比如.7z
等):
$ lsregister -dump
...
Container mount state: mounted
bundle id: 2592
Mach-O UUIDs: 88225C07-0FDC-3875-A3B4-C5328E509B9E, 20A99135-975D-3A7B-A8DD-B7DF2CE428D0
path: /Users/user/Downloads/Mac File Opener.app
name: Mac File Opener
identifier: com.pcvark.Mac-File-Opener (0x80025f61)
executable: Contents/MacOS/Mac File Opener
--------------------------------------------------------
claim id: 31508
name: DocumentType
rank: Alternate
roles: Viewer
flags: doc-type
bindings: .7z
...
一旦应用(或者广告软件)自动注册了document handler,那么当用户尝试打开匹配的文档时,应用或广告软件就会被自动调用。
这个过程由launch services framework
负责,更具体一些,是_LSBundleCopyOrCheckNode
方法(以及_LSBundleCopyOrCheckNode_block_invoke
)负责匹配过程(查找与文档类型匹配的已注册的应用)然后执行已注册的应用:
(lldb) b ___LSBundleCopyOrCheckNode_block_invoke
...
(lldb) x/gx $rdx
0x700000115c48: 0x00007fd3b4a9c520
(lldb) po 0x00007fd3b4a9c520
<FSNode 0x7fd3b4a9c520> { flags = 0x00000020, path = '/Users/user/Desktop/Mac File Opener.app' }
总结一下:
1、应用程序可以“声明”能够处理的各种文档或者文件类型;
2、一旦应用落盘,操作系统就会自动注册这些“document handler”;
3、文件打开时,系统会查询“launch services”数据库,确定该执行哪个应用。
以上就是“document handlers”的大概内容,接下来讨论一下自定义URL Scheme handler。从操作系统的角度来看,这种URL Scheme handler通常只是适用于url的document handler。
这对自定义URL Scheme handler来说意味着两点:
1、一旦(“声明”支持这些handler的)应用落盘,macOS会自动注册自定义的URL Scheme handler;
2、当自定义URL Scheme被调用时,就会触发(已自动注册的)handler应用。
由于这些操作都可以被网页触发,因此我们很容易就能猜到会出现什么后果。
之前我曾在Box 2017上讨论过自定义URL Scheme话题(“Oversight: Exposing Spies on macos”)。
然而当时并没有涉及到恶意软件或者恶意利用之类的内容。
由于我还没有接触WINDSHIFT
恶意软件样本,我之前自己写了PoC示例,演示了攻击者如何滥用自定义URL Scheme handler来远程感染Mac主机(该过程涉及一些用户交互操作)。
我们先创建Xcode项目,使用Cocoa App模板:
应用本身的逻辑并不关键,但我们必须编辑应用的Info.plist
文件,以便“声明”我们将支持一个自定义的URL Scheme。在Xcode中,我们添加了一个URL types
数组,指定了Scheme的名称(windshift://
)以及一个URL标识符:
观察原始的plist,我们可以看到这些信息对应其中的一些key,比如CFBundleURLTypes CFBundleURLSchemes
以及CFBundleURLName
:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>windshift</string>
</array>
<key>CFBundleURLName</key>
<string>com.foo.bar.WindShift</string>
</dict>
</array>
一旦该应用编译(或下载)完毕,lsd
就会解析应用的bundle数据(特别是Info.plist
文件),检测是否存在自定义URL Scheme handler,如果有则进行注册。注意这些操作都会自动完成。
为了确认这一点,我们可以转储“launch services”数据库(通过lsregister -dump
命令)。其中的确可以看到我们的PoC应用(WindShift.app
),以及我们自定义的URL Scheme(CFBundleURLSchemes: (windshift)
):
--------------------------------------------------------------------------------
BundleClass: kLSBundleClassApplication
Container mount state: mounted
bundle id: 168204
Mach-O UUIDs: E2E77A08-F458-36C1-B7BD-99F409B4DEAC
Device Familie
Counterpart ID
sequenceNum: 168204
FamilyID: 0
PurchaserID: 0
DownloaderID: 0
installType: 0
appContainer: #
dataContainer: #
path: /Users/patrick/Projects/WindShift/DerivedData/WindShift/Build/Products/Debug/WindShift.app
name: WindShift
....
executable: Contents/MacOS/WindShift
....
CFBundleURLTypes = (
{
CFBundleURLName = "com.foo.bar.WindShift";
CFBundleURLSchemes = (
windshift
);
}
);
}
claim id: 386204
name: com.foo.bar.WindShift
rank: Default
roles: Viewer
flags: url-type
icon:
bindings: windshift:
如果我们现在使用浏览器(这里使用的是Safari),“浏览”我们的自定义URL Scheme(windshift://
),我们可以确认自定义的URL Scheme已被自动注册:
如果我们点击“Allow”(这是个危险操作,后面我们会详细介绍),那么应用就会被启动:
三、远程利用
如果我们“不怀好意”,可能就会看到这种技术的利用方向。现在我们将介绍如何滥用自定义URL Scheme,远程定位(并在理想情况下感染)Mac用户的一种方法。
首先,目标必须浏览我们可控的一个网站。WINDSHIFT
APT组织(成功使用了)钓鱼邮件这种途径。
一旦目标浏览我们的恶意网站,就会触发下载操作,下载包含恶意应用的一个归档(.zip
)文件。如果Mac用户正在使用Safari
,那么归档文件就会自动被解压,这是因为Apple认为自动打开“安全的”文件是一个比较明智的选择。这一点非常重要,这意味着恶意应用(而不是一个单纯的压缩zip文件)现在会存在于用户的文件系统上,这样就会自动触发自定义URL Scheme handler的注册过程,这一点的确应该好好谢谢Apple。
现在恶意应用的自定义URL Scheme已成功注册(在目标系统中),恶意网站中的代码就可以加载或者“浏览至”自定义的url地址,使用JavaScript可以轻松完成这个任务:
window.location.replace('windshift://');
macOS在后台会查找处理这个自定义URL Scheme的handler,最终就会找到我们的恶意应用(刚刚下载到目标系统中)。一旦查找完毕,操作系统将尝试启动恶意应用来处理所请求的URL!
(对Mac用户来说)幸运的是,较新版的Safari中会弹出一个警告信息:
然而引号中的字符其实可以被攻击者所控制,因为这些字符就是应用的名称。因此,我们很容易就可以让弹出的警告窗口看起来比较普通、无害甚至有趣:
注意:
通常情况下应用无法使用类似
.txt
或者.com
之类的扩展名。然而,由于应用名可以包含unicode字符,因此我们可以利用homograph这种攻击技巧。
这样我们就可以让恶意应用的名称变成类似
Attachment.TXT
之类的字符串(其中“X”其实是卡里安(Carian)字母X)。
虽然最新版的Safari会在启动已注册自定义URL Scheme的应用前提示用户,但老版本的Safari(比如默认安装在EI Capitan上的Safari)就不会执行这种操作。相反,这些版本的Safari并不会弹出任何警告信息,会盲目地启动(恶意)应用。
抛开Safari的版本,我们还有另一个障碍要绕过:文件隔离(File Quarantine)。
如果应用文件下载自互联网,那么当用户执行该应用时,文件隔离机制就会弹出警告窗口:
好消息是有些Mac用户会点击Cancel
按钮,但仍有些Mac用户还是会点击Allow
按钮(Taha已经确认了这一点,他在演讲中提到WINDSHIFT
APT组织已经成功利用了这种攻击向量)。
此外,我们还可以控制应用的名称,因此可能会让更多用户点击Allow
按钮,比如,我们可以添加个emoji表情试一下?
注意:
这里大家可能想知道为何Gatekeeper没有发挥作用?
在默认配置下,Gatekeeper只允许经过签名的应用。WINDSHIFT APT组织所使用的恶意软件都带有签名(现在大多数恶意软件都会使用这种方法),因此并没有轮到Gatekeeper上场。
在本文总结之前,我绘制如下一张图,介绍了这种“自定义URL Scheme handler”攻击的详细流程:
四、总结
我们并不是每天都能看到针对Mac用户的APT组织,更何况这类恶意软件使用了相当新颖的感染方式。然而,我们再也不能天真地认为Mac用户能够免受这类威胁的侵扰,WINDSHIFT
APT组织已经给我们好好上了一课。
在本文中我们讨论了macOS的一些功能,比如document handler以及自定义URL Scheme handler,演示了这些功能如何被恶意软件主动利用。幸运的是,这类攻击方法(特别是在新版本的macOS上)需要一些用户交互操作。然而,这两种功能已经在实际攻击活动中被成功利用,因此如果大家正在寻找感染Mac用户的可靠方法,可以考虑使用这些技术。
如果你是Mac用户,并且比较注重安全,那么可以考虑使用Google Chrome浏览器:
如果你习惯使用Safari,至少需要关闭下载文件的自动解压功能,因为只有在应用被解压时才会触发(恶意)自定义URL Scheme handler的注册操作。
如果想关闭这个功能,请打开Safari的首选项,在General
选项卡,勾掉Open "safe" files after downloading
这个复选框:
此外,我们还可以将Gatekeeper设置成“仅允许来自Mac App Store的应用”(然后根据需求小心允许第三方应用),这一点并不会带来什么坏处。