top of page
Search
  • Writer's pictureIYP

攻击者如何借助授权插件,实现 macOS 持久化凭据窃取

攻击者在目标主机上成功实现权限提升后,要做的第一件事往往就是窃取凭据。


概述


攻击者在目标主机上成功实现权限提升后,要做的第一件事往往就是窃取凭据。随着系统完整性保护(SIP)机制的引入,macOS 上的凭证窃取似乎变得更加困难。攻击者无法再使用例如从安全进程中提取主密钥、解密目标用户登录密钥链这样的方法。在这里,展示了一个例子。SIP 机制可以防止任何用户(甚至包括 root 用户)修改系统文件、目录和进程。这样一来,攻击者就开始尝试使用其他方法进行凭证窃取,这些方法包括:记录键盘键入、提示用户输入凭据、获取本地文件系统中以纯文本形式保存的凭据。此外,还有一种被称为“授权插件”(Authorization Plugins)的替代方案。


授权插件用于扩展授权服务 API,从而实现操作系统本身不支持的机制。一个合法的用例是使用 Duo 等第三方软件,实现多因素身份验证。每个插件中可以包含多个机制,或者是实现自定义逻辑以执行授权的函数。这些机制也存在于策略数据库中。这些数据库中包含对各种授权权限的定义。针对特定授权权限的定义中,都可以引用几种机制,每种机制与其相应的授权插件相配对。Apple 在这里简单介绍了其工作原理。


实际上,loginwindow 进程尝试获取 system.login.console 权限。策略数据库中的定义,详细列出了发生这种情况时执行的几种机制。并且,也可以将自定义插件及其机制插入到该列表中。列表中条目的位置,以及插件在登录过程中与操作系统的交互方式,共同决定了在什么时间执行该条目。此外,插件可以配置为在特权环境或非特权环境中运行,这一点由策略数据库中的条目字符串来指定。针对特权执行,需要将“,privileged”附加到机制条目中。如果希望访问 UI,并且需要向用户弹出提示,那么就可以选用非特权插件。关于插件环境问题的更多信息,请参考这里。


在授权插件中,有一个值得关注的特性,就是能够在插件之间传递上下文值。这一特性也经常被攻击者使用。这些值中包含关于有关用户的详细信息,包括主目录、UID,甚至是明文密码。这一特性存在的目的是希望同时使用特权插件和非特权插件的开发人员,能够以相对简单的方式在两者之间实现数据的共享。对于攻击者来说,授权插件是一个能够窃取凭据、保持持久性的理想机制。如果能持久性的进行凭据窃取,那么就可以在登录过程中的任何位置执行特定代码。至于如何安装授权插件,则是一个相对简单的过程,我们将在下一节中详细讲解。


安装授权插件


授权插件由两部分组成:包含磁盘上所有插件代码的 bundle 文件、授权数据库中的一个条目。安全服务器会根据授权数据库中的规则和策略,授予特定用户相应的权限。应用程序可以通过 AuthorizationRightSet、AuthorizationRightGet 和 AuthorizationRightRemove API 调用,在任意特定时间修改规则。如果需要向数据库中添加条目,应该调用 AuthorizationRightSet 函数,同时引用包含每个身份验证机制键和值的 NSDictionary。在 Apple 给出的文档中,展示了一个示例。除此之外,AuthorizationRightGet 函数可用于获取现有权限的 NSDictionary 值。随后可以修改字典,并使用 AuthorizationRightSet 函数为自定义授权插件添加条目。这是 Python 的一个示例。


此外,还可以通过安全命令行工具修改授权数据库。如果攻击者想要在 system.login.console 策略中添加恶意插件,他们需要先将授权数据库中的策略读入 plist 文件:

security authorizationdb read system.login.console >> system.login.console.plist

然后按照下列格式,将其插入到 bundle 中,作为其中的一种机制:

<string>[Plugin Name]:auth,privileged</string>

PlistBuddy 也可以使用以下命令执行此操作:

/usr/libexec/PlistBuddy -c “add :mechanisms:[HomeDir Offset] string [bundlename]:login,privileged” <Plist filename>

在更新 plist 文件后,使用以下命令,将更改同步到数据库中:

security authorizationdb write system.login.console < /path/to/plist/file

武器化


接下来,我们使用 Xcode,尝试创建一个插件,然后为 Payload 执行添加相应的逻辑。在这个例子中,我们将使用 Shell 命令,来启动Apfell Payload,但实际上 Python Payload 也可以工作。


1、首先打开 Xcode,并选择“创建一个新的 Xcode 项目”选项。

2、在 macOS 系统中,选择 bundle 模板,为项目进行命名,然后单击“下一步”。



3、接下来,下载并保存项目文件夹中列出的所有三个文件。右键单击导航窗格中的项目文件夹,将这三个文件添加到项目中,然后选择将文件添加到“[你的项目名称]”。



4、然后,设置 Apfell,并生成 JXA Payload。关于设置 Apfell 的方法和创建 Payload 的相关说明,请参考@its_a_feature_的博客文章


5、复制以 osascript -l JavaScript 开头的一行 JXA 代码,并将其放到适当的位置。



6、从顶部菜单栏中选择项目,点击“构建”。生成的包将会显示在左侧导航窗格的项目目录下。右键点击 bundle 文件,然后选择在 Finder 中显示。随后,即可将文件复制到我们指定的可访问位置下。




至此,插件应该就可以安装了。我们可以使用命令行工具,或者安装过程中描述的授权 API 来完成这一任务。


在安装插件后,需要重新启动计算机,或者进行注销后重新登录,才能触发执行。请注意,该插件将加载到位于此处的 authorizationhost 进程中:

 /System/Library/Frameworks/Security.framework/Versions/A/MachServices/authorizationhost.bundle/Contents/MacOS/authorizationhost

在下面的视频中,展示了安装和执行授权插件的过程。用于演示的Xcode项目请参见



检测方法


为了实现对这一攻击行为的检测,我们可以查看 /Library/Security/SecurityAgentPlugins 目录下的文件创建规则,授权插件只能安装在该目录中。文件创建事件的示例 osquery 规则如下:

SELECT * FROM file_events WHERE target_path LIKE '/Library/Security/SecurityAgentPlugins/%' AND action = 'added';

在修改授权数据库时,基于所使用的安全二进制文件的命令行签名应该有助于检测。此外,针对个人用户,我强烈建议安装 Objective-See 提供的一些安全软件。例如,持久性扫描程序 KnockKnock 中,自从 2015 年以来就加入了授权插件的检测规则。



利用授权插件,是添加持久性和窃取凭证的一种高风险、高回报方法。其高风险在于,如果插件的安装过程出现问题,目标用户很可能会产生怀疑,并且可能会引起防护软件的告警。其高回报在于,这种方式提供了一种有效的凭据窃取和代码执行方式。即使最终用户修改了密码,攻击者也可以不断获取新的凭据。同样,攻击者也可以使用 mimikatz 以及相应的安全支持提供者(SSP)程序,在 Windows 系统上实现此目的。◾️

16 views0 comments
bottom of page