首页
社区
课程
招聘
[翻译]通过一次点击打破 macOS 防御
发表于: 2018-10-15 19:58 5626

[翻译]通过一次点击打破 macOS 防御

2018-10-15 19:58
5626

想象一下,你是一个攻击者(或者是恶意软件的一部分),已经成功的控制了Mac,天喏!

你可能想去做这样的事:

把用户的keychain都dump出来

确定系统的(地理)位置

遍历用户的联系方式

加载一个内核扩展(kext)

绕过第三方的安全产品

不幸的是(对作为攻击者的你来说),在最新的macOS版本中,几个新的安全机制阻止了这些操作,现在,这些安全机制会弹出警告框来响应这些操作。警告框被设计成了只能用户才能响应,例如这样:

然而,如果我们能找到一个途径通过编程,或者“模拟”响应这些警告框,我们可以一下子绕过所有这些安全机制,也就是说,如果这样的攻击存在,可以从UI上单点攻破,这篇Blog探究了macOS模拟点击事件的很多个方面...从恶意软件滥用这些功能,到新的仍未修补的0day攻击!

模拟点击(或者说编程)和UI交互来达到恶意的目的并不是什么新鲜的想法,让我们看看一些(滥用)使用这种事件的恶意软件。

OSX.FruitFly是在十年前的写出来的,在2017年初才被发现,我之前写了一篇很长的关于这个恶意软件的白皮书("Offensive Malware Analysis: Dissecting OSX.FruitFly.B via a Custom C&C Server")。并指出它能够生成“模拟”鼠标和键盘事件:

这是一个简明的gif,演示了远程攻击者如何通过OSX.FruitFly远程关闭(keychain)安全访问提示:

另一个利用“模拟点击”事件的Mac恶意软件(2011年)是OSX.DevilRobber。

正如大牛@noarfromspace所指出的,它dump了用户的keychain,通过几个简单的 AppleScript 命令绕过“keychain访问”提示符:

广告软件也以使用“模拟”事件而闻名。例如,OSX.Genieo将自己安装为浏览器扩展。然而,为了实现这一点,OSX.Genieo必须绕过一个试图阻止(Safari)浏览器扩展的编程方式安装的安全提示。Adware如何绕过这个警告?通过发送一个“模拟”鼠标事件来点击“允许”!

具体来说,对OSX.Genieo的方法dump分析(通过jtool),我们能看到一个叫SafariExtensionInstaller的class。

猜猜这个clickOnInstallButton按钮做了什么?!

首先,它通过调用一个名为getPopupPosition的方法来获取警告框(“弹出”)的位置。然后它通过CGEventCreateMouseEvent和CGEventPost api发送一些“模拟”鼠标事件。0x5是鼠标移动事件,而0x1和0x2对应的是左键按下,然后抬起。最终的结果吗?该广告软件能够解除警报,并安装自己,成为一个恶意浏览器扩展。

在macOS的最新版本中,苹果已经实施了各种防御措施来阻止这种“模拟”攻击。然而,这些防御不是通用的,而是只保护某些UI组件(例如某些安全或访问提示)。

在High Sierra(以及可能的macOS旧版本)上,只要有人试图发送代码生成的鼠标事件,例如发送到keychain访问提示,操作系统会检测并阻止这个:

具体来说,macOS将检查生成“模拟”事件的过程是否提供了辅助访问(是的,辅助访问提示符也被保护不受此类攻击):

注意,“辅助访问”必须手动给应用程序。通过系统的偏好设置,您可以查看有这个权限的应用程序。或者,你可以dump(SIP保护的)操作系统隐私数据库,/Library/Application Support/com.apple.TCC/TCC.db:


通过CoreGraphics API生成的“模拟”事件现在也被过滤和屏蔽(但同样,只有当目标UI组件被显式地保护时),可以在以下系统日志输出中看到:

如果我们正则查找“Sender is prohibited from synthesizing events”字符串,我们可以在核心库中的post_filtered_event_tap_data函数中找到它。

正如我们在上面的反编译中看到的,如果CGXSenderCanSynthesizeEvents函数返回0 (false/NO),就会记录这个错误消息。如果sandbox_check_by_audit_token方法失败,就会发生这种情况。

就像它的名称建议的一样,sandbox_check_by_audit_token函数检查发送“模拟”事件的进程是否具有隐藏控制权限。这个检查似乎是在内核中执行的,在mpo_iokit_check_hid_control_t函数中:

好的,让我们戴上黑客帽(黑色的?,白色的?灰色的?)讨论一些漏洞和0days!

我的目标很简单:在一个完全打补丁的High Sierra系统上“模拟”与任何/所有UI提示(安全、隐私、访问等)....作为一个普通用户来做一些事情,比如dump密钥链,或者批准一个内核扩展来加载!

在研究探索之后,我发现了一个叫做“鼠标按键”的功能

“鼠标键”是macOS的一个有文档记录的特性,正如苹果公司所指出的,它允许你把键盘当作鼠标来使用!可以使用鼠标右键,例如将鼠标移到右边,只需按键盘上的O(或numberpad 6)就可以了。生成鼠标点击?按I(或numberpad 5):


这引发了问题:

■“鼠标键”可以编程来模拟吗?
■一个“模拟”键盘事件,可以生成一个被信任的(阅读:允许)“模拟”鼠标事件吗?

这两个问题的答案都是肯定的!

首先,我们可以使用AppleScript以编程方式打开系统首选项应用程序的窗口,该应用程序具有启用“鼠标键”的复选框。并使用CoreGraphics发送“模拟”鼠标检查来启用:

由于苹果只保护某些UI组件(比如安全警报)不受“模拟”事件的影响——而这些UI组件没有受到保护,正好适合我们去做!


要生成编程鼠标单击,启用“鼠标键”,我们首先移动鼠标,然后通过AppleScript发送一个“模拟”键盘事件。具体来说,我们模拟键87:

当启用“鼠标键”时,当“按下”(甚至以编程方式)keycode 87(映射到numberpad 5)时,系统将其转换为鼠标单击!这可以通过我的开源鼠标和键盘嗅探器观察到,嗅探器:

因为操作系统是做键盘到鼠标事件的转换,然后“传递”鼠标事件(点击),甚至受保护的UI组件将接受和处理事件!(一般来说,当源是操作系统本身时,这些受保护的组件信任“模拟”事件)。

那么我们能用这种能力做什么呢?很多事情....像dump和泄漏用户的密钥链与所有的私钥和未加密密码:

我负责地向苹果公司报告了这个bug,苹果将漏洞命名为CVE-2017-7150,并在通过高版本的Sierra追加补丁修补了漏洞。


但是,“模拟”问题仍然比比皆是!

首先,我注意到各种与隐私相关的警告(即使是在一个打满补丁的macOS 10.13上。* box)盲目接受程序化鼠标事件。例如,在macOS的最新版本中,macOS在代码试图访问时显示警告:

■系统(用户)的地理位置
■用户的联系人
■用户的日历事件
■……和更多!


由于这些警报接受“模拟”事件,恶意软件可以简单地通过编程方式忽略它们:

这里有一个POC,它可以通过“模拟地”忽略操作系统的访问警告来确定用户的地理位置:


…你可能会想,“苹果,如果恶意软件可以如此简单地绕过它,为什么还要发出警告呢?”也许他们可以告诉答案,因为我也一脸懵逼!

好吧,事实证明还有一个更糟糕的问题。允许非特权恶意软件或攻击者与“受保护的”UI组件交互的问题——例如High Sierra的“用户辅助内核加载”接口。是的,这也适用于完全修补的macOS 10.6。*系统。

发现这个bug是一件令人尴尬的意外。我试着测试苹果的CVE-2017-7150补丁,并错误地剪切和粘贴了一些代码。结果是,可爱的0day!

回顾一下,可以通过CoreGraphics框架发送“模拟”鼠标事件。通常对于这样的鼠标点击,您发送两个事件:一个鼠标按下事件,然后是一个鼠标抬起事件:

但是,如果复制并粘贴第一行:CGPostMouseEvent(point, true, 1, true);…并且忘记将最后一个参数从true更改为false(表示鼠标抬起移动),这将生成两个鼠标按下事件。

…理论上这个应该被忽略。然而,事实并非如此!正好相反(通过SniffMK),我们可以观察到系统将第二个(无效的)鼠标按下转换为抬起的鼠标:

问题不在于第二个鼠标下移事件被转换为鼠标上移事件,而是它是由操作系统完成的,这意味着事件的源进程id为0(即系统)。如前所述,一般来说,UI(包括安全提示和其他受保护的组件)允许系统发生“模拟”事件(pid 0),例如,将一个典型的鼠标按下/抬起事件发送到“用户辅助内核加载”界面的“允许”按钮,会被忽略,错误如下:

但如果pid是0呢?如前所述,这将是允许的!


我们现在可以通过编程允许内核扩展的加载,即使是在一个完全打补丁的高版本Sierra系统上。

在OSX/macOS上,一个人总是需要root权限,才能加载这样的扩展。那么这次攻击给我们带来了什么好处呢?或者更确切地说,问题是,“用户辅助内核加载”的首要目的是什么?

在macOS的最新版本中,加载kext不仅需要是root用户,还需要对kext进行签名。从苹果公司获得内核代码签名证书几乎是不可能的。

但是攻击者(具有root权限)可以做的事情(正如我在2016年DefCon演讲中详细介绍的那样)是:
加载已知的易受攻击的第三方驱动程序(已经合法签名)
利用已知的漏洞在内核上下文中获得任意代码执行。

苹果对这种攻击的回应是“用户辅助内核加载”,它要求用户必须手动批准任何kext的加载,从而增加了额外的安全层。遗憾的是,我们刚刚展示了这个“安全”机制(通过CVE-2017-7150),仍然100%是坏的。谁承担这个后果?第三方开发者(而不是那些坏家伙)被迫遵守苹果的规则:

###不可见

这些利用“模拟”事件的攻击的一个明显缺点是它们是可见的。

想象一下,你正坐在办公桌前用Mac电脑工作……突然,一个警告弹出,鼠标似乎自动地移动到警告,并点击取消它。你肯定知道你被黑了!

幸运的是(对于攻击者/恶意软件)有一个简单的解决方案!只需要把屏幕调暗:


当屏幕亮度调到0.0时,UI仍然是完全“显示”和活跃的(与显示器锁定或屏幕保护程序打开时不同)。然而,它在用户看来是“关闭”的,因此任何“模拟”攻击都是不可见的。

现在,您要确保您(作为攻击者)在适当的时间将屏幕调暗。例如:

当显示器进入休眠状态时。

在后一种场景中,代码可以检测显示器何时即将进入休眠(通过kiomessagecandeviceoff通知)。在这里,它可以迅速将屏幕亮度调暗到0.0,然后在显示器休眠之前执行任何“模拟”攻击:

通过(滥用)使用模拟事件,恶意软件或本机攻击者可以绕过macOS的大量内置安全机制:

尽管苹果已经意识到了这种攻击方式,并试图保护操作系统的安全与隐私相关的UI组件,但它们都失败了。即使在一个完全补丁的高Sierra系统上,也可以“模拟”与这些UI组件交互,从而在不可见的情况下忽略这些组件。


[注意]APP应用上架合规检测服务,协助应用顺利上架!

最后于 2019-2-2 11:11 被kanxue编辑 ,原因:
收藏
免费 1
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  junkboy   +1.00 2018/10/15
最新回复 (1)
雪    币: 11716
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢  建议附上原文链接
2018-10-15 20:01
0
游客
登录 | 注册 方可回帖
返回
//