一、前言
如果大家关注我们之前在MDSec上发表过的博文,可以看到我们最近在macOS方面的研究成果。
作为红方,在攻击Windows端点时我们可以使用各种各样的手段,比如HTA、OLE、包含宏的Office文档或者伪装成合法应用的简单二进制程序,我们总有各种办法在钓鱼攻击中获得目标主机的访问权限。
不幸的是,对于macOS系统来说我们的运气并没有那么好。如果我们在网上搜索一番,会发现很难找到在攻击macOS时可以为我们所用的技术。
在本文中,我想给大家介绍我们在研究过程中发现的一些小发现,这些小发现很难独立撑起一篇完整的文章;也会与大家分享一些小技巧,可能对大家在下次攻击macOS时有所帮助,或许能借此在系统中获得立足之地。
二、面临的障碍
在面对macOS系统时,我们会面临什么样的障碍?令人惊讶的是,第一个障碍也是最容易绕过的障碍:Gatekeeper。
Gatekeeper是macOS在防御从互联网下载恶意应用时的第一道防线。
普通Mac用户肯定对如下提示窗口非常熟悉:
从这个提示窗口中,macOS告诉我们已下载的这个应用并不可信,这主要是因为缺少代码签名证书。
毫无疑问,在渗透过程中我们的任务是尽可能模仿真实攻击者已使用的一些技术。查看恶意软件分析报告,我们可以快速找到真实攻击环境中攻击者如何绕过这个限制:
如上图所示,方法其实很简单,那就是使用有效的开发者账号来绕过该限制,这也是恶意软件开发者采取的方法。
显然,通过任何恶意方法获得证书并不可行,也就是说我们要么选择购买有效的开发者账户,成功绕过Gatekeeper,要么扩展我们的社会工程学技巧,说服用户帮我们绕过Gatekeeper。
在下文中我们采用的是第一种方法,然而在实际攻击场景中,这种方法有个明显的缺点,那就是会将开发者证书与恶意软件关联起来。
那么我们如何才能构造足够迷惑人的诱饵,成功突破目标呢?
三、APP文件
几星期以前(实际上是几个月以前,这篇文章已经构思了好长一段时间),我在推特上公布了一个截图,介绍了如何在钓鱼攻击中隐藏一个app:
大家可能知道,在之前版本的macOS中,我们有可能将某个文件命名为mysecrets.docx.app
。在这种情况下,macOS会自动移除.app
扩展名,这样用户一开始观察这个文件时可能以为看到的是.docx
文件。
然后Apple做了一些修改,现在如果在.app
扩展名之前的文件扩展名已注册,那么就会显示完整的扩展名。比如,如果我们将某个文件命名为mysecrets.docx.app
,那么我们看到如下画面:
有趣的是,无效的扩展名并不会显示出完整的.app
名。比如,如果我们将应用重命名为secrets.docy.app
,我们可以看到如下画面:
那么我们如何才能在满足如上限制条件的前提下,构造出更有欺骗性的诱饵呢?好吧,其实我们可以利用“同形字”技术来绕过对合法文件扩展名的检测。比如,如果我们使用IronGeek的Homoglyph Generator工具,可以看到许多可选项,能够呈现近乎相似的文件扩展名:
简单选择合适的同形字符后,我们可以满足如上限制条件,并且能够成功隐去.app
扩展名。然后接下来我们需要为我们的载荷构造一个图标,如下所示:
四、投递APP
现在我们已经构造完载荷,也具备欺骗性的文件名,现在我们需要将载荷发送给我们的受害者。不幸的是,与Windows环境不同,在这种场景下我们不能使用文件链接方式或者将其封装到一片HTML数据中,这是因为.app
实际上是一个目录,我们需要在发送之前进行打包。
为了投递文件后增加攻击成功的概率,我们需要理解目标会通过那种方式下载我们的载荷。
假设经过踩点后,我们知道目标使用的是Safari,那么这正合我们意,因为Safari会帮我们自动下载并解压文件,只给用户呈现一个非常有诱惑力的图标,留待用户点击:
但我们很快发现用户所选择的浏览器并不是我们需要考虑的唯一因素,如果受害者使用的是其他解决方案,比如Google Mail呢?此时我们就会遇到问题。在这种情况下,Google通常会提供.zip
文件的预览,这样用户很快就会发现我们的文件不是.docx
文件,而是一个.docx.app
文件,提高警觉度。
那么我们如何解决这个问题?我们知道macOS将Archive Utility作为解压缩文件的默认解决方案。启动Archive Utility后,我们可以看到该工具支持3种文件类型:
也就是说,支持以下3种文件:
- 压缩文件:
cpgz
- 常规归档文件:
cpio
- Zip归档文件:
zip
我们知道Google Mail会自动解开.zip
文件,但其他两种文件会怎么处理呢?
对于CPGZ
文件,我们可以看到包含在其中的CPIO
文件:
如果我们使用的是CPIO
:
非常棒,根据前面的测试结果,如果我们发送的是.cpio
文件,Google Mail只会简单提示用户下载该文件,但这个文件名本身有没有问题?受害者看到一个.cpio
文件时会不会有所警觉?
让我们加载Archive Utility来看看我们是否可以找到解决办法。我们可以使用Hopper
工具分析Archive Utility,先来看看[BAHController doUnarchiveFile:]
这个方法:
其中包含一个函数调用:[BAHController dearchiveItem:withController:isIntermediateItem:]
以上代码调用了+[BAHCodec decompressorForFile:andOptions:]
,从中我们可以看到应用使用了+[BAHDecompressor classNameForFile:checkMagic:isPrimaryArchive:]
方法来判断应该选择哪种解压器。
首先我们可以看到应用会搜索常见的几种文件扩展名:
代码逻辑非常直白,一旦找到支持的文件扩展名后,我们可以看到如下调用:
r13 = [BAHDecompressor reconcileClassName:r13 withMagic:[[BAHController sharedInstance] magicInfoForFile:r12] isPrimaryArchive:sign_extend_64(var_2C)];
第一个调用为-[BAHController magicInfoForFile:]
,这是/usr/bin/file
工具的简单封装函数,可以无视文件的扩展名,获取文件的具体类型。输出结果传递给+[BAHDecompressor reconcileClassName:withMagic:isPrimaryArchive:]
,确保文件扩展名与file
的输出相匹配:
继续跟踪,我们可以看到file
会识别魔术字节(magic byte),根据这些信息判断文件类型(而非文件扩展名),选择匹配的解压缩器。
这意味着我们可以创建Archive Utility支持的各种归档文件(如CPIO
、GZIP
等),然后随便使用支持的其他文件扩展名(如.cpio
、.tar.gz
、.uu
、.zip
等),这样Archive Utility就会自己会去处理这些不匹配因素。
利用这些知识点,我们可以创建一个CPIO
文件,然后将其重命名为.zip
文件:
非常棒,Google Mail只会显示一个错误信息,提示用户下载。当受害者访问该文件时,可以看到Achive Utility会正常解压出我们的文件。