macOS红蓝对抗:如何欺骗具有特权的帮助工具以获取root权限 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

macOS红蓝对抗:如何欺骗具有特权的帮助工具以获取root权限

41yf1sh 系统安全 2019-12-12 10:44:31
588110
收藏

导语:在本文中,我们将探索一些新颖的方式,可以滥用AppleScript的功能来欺骗用户已经在本地系统上信任的特权进程。

概述

我们在此前的文章曾经提到过,macOS权限提升通常是通过诱导用户,而不是利用0-day或未修复的漏洞来实现的。从红队的角度来看,有一个可能提供帮助的本地工具——AppleScript。AppleScript可以轻松、快速地产生虚假的授权请求,这些请求在用户看起来可能很有说服力。尽管这并非一项新的技术,但在本文中,我们将探索一些新颖的方式,可以滥用AppleScript的功能来欺骗用户已经在本地系统上信任的特权进程。

什么是具有特权的帮助工具?

Mac上的大多数应用程序都不需要权限提升就可以执行工作。如果是从Apple的App Store购买的应用程序,从技术上来看,它们是不允许提升权限的。尽管如此,有时应用程序确实有充分合理的理由,需要获取比当前登录用户更大的特权。我们根据Apple提供的文档,梳理了几种情况:

1、操纵文件的权限,文件的所有权;

2、创建、读取、更新或删除文件;

3、打开用于TCP或UDP连接的特权端口;

4、打开原始Socket;

5、管理进程;

6、读取虚拟内存中的内容;

7、更改系统设置;

8、加载内核扩展。

通常,应用程序如果需要执行上述任意功能,通常只是偶尔需要执行一次。针对这种情况,在需要执行的当时要求用户授权是有必要的。但是,尽管请求用户授权这件事是为了提升安全性,但如果应用程序在某些场景中过于频繁请求用户授权执行这些动作,对用户而言会造成一些不便。用户不喜欢重复出现的对话框警告,也不喜欢重复多次输入密码。

为了解决这一问题,开发人员提出了特权分离的技术。通过创建功能受限的独立“帮助程序”来执行这些任务,仅在安装时要求用户授权安装这些帮助工具。在日常使用过程中,我们可能见过类似于以下的权限请求:

1.jpg

帮助程序工具始终会以提升的权限来运行,但是其功能是有限的。至少从理论上讲,该公欧只能按照父程序的要求执行特定任务。这些特权帮助工具位于本地“Library”(库)文件夹的子文件夹中:

/Library/PrivilegedHelperTools

由于它们仅由来自App Store外部的第三方应用程序安装,因此只有部分用户会在系统中安装某些软件。然而,有一些非常流行、被用户广泛使用的macOS软件已经使用了这类工具。由于操作系统并没有移除独立的特权帮助工具,因此,我们对一些操作系统进行排查,很有可能发现其中一些具有特权的帮助工具正在使用中。以我的操作系统为例,我在系统中发现了一些具有特权的帮助工具,具体是:

BBEdit;

Carbon Copy Cloner;

Pacifist。

父进程和特权帮助工具之间可能会滥用这一信任机制(参考CVE-2019-13013漏洞),但这并不是我们今天想要尝试的方法。相反,我们将利用这样的一个事实,即用户非常熟悉这些特权进程的父应用程序,并且会习惯性地信任来自它们的授权请求。

为什么要使用AppleScript进行欺骗?

有效的社会工程学攻击需要依赖于良好的上下文环境。当然,我们可以随时抛出一个虚假的用户警报,但如果想使其更具迷惑性,我们希望这个警报具有以下的特点:

1、看起来更加真实:包括在警报中使用令人容易信任的文本、具有迷惑性的标题以及具有相关性的图标。

2、出于令人信任的理由触发:如果一个与业务无关,或者从没有要求过特权的应用程序触发了用户警报,将会有很大概率引起用户的怀疑。因此,以具有特权的帮助工具作为目标将非常关键,特别是在我们提供足够真实的详细信息以便用户进行确认,这会增加提示信息的可信性。

3、在适当的时间触发:例如,可以选取当前用户正在使用我们试图仿冒成的应用程序时。

利用AppleScript,上述所有要求都非常容易实现。下面是一个例子,我们可以尝试使用AppleScript来创建。

2.jpg

这个对话框实际上是非常粗糙的。可以看到,这里没有使用输入用户名和密码的两个字段。但即使如此,这个对话框也有一定的迷惑性。其中包含一个有效的标题、一个有效的图标饿一个有效的进程名称,如果用户需要进一步确认,用户会找到相应的具有特权的帮助工具。具体而言,用户在验证的过程中,会发现这个帮助工具确实位于自己的/Library/PrivilegedHelperTools文件夹中。用户必须深入挖掘,才能真正发现我们的欺诈行为。

当然,一些对其怀疑的用户很可能会直接按下“取消”键,而不会进行过多的深入挖掘。但幸运的是,使用AppleScript,我们可以使得用户在按下“取消”按钮后杀死父应用程序,或产生无限循环的代码,从而使这一请求看起来更具说服力,并且阻止目标用户再次点击“取消”键。

但是,无限次重复的情况可能还会引起用户的怀疑,但是杀死父应用程序并发出合适的警报来“解释”这种情况似乎更为合理。当用户重新启动父应用程序,并再次触发我们的授权请求时,用户会更有可能输入密码,并继续其工作。

为了实现良好的效果,我们还可以针对用户首次尝试输入的密码弹出错误提示,并让用户输入两次。由于输入的内容不会在用户屏幕上显示,因此用户也并不清楚自己是否在第一次时无意出现错误。强制用户输入两次时,我们可以判断第一次用户的输入是否正确,并在第二次输入验证通过之前,先验证用户密码。在本文中,我们将不会过多描述这一技术细节,此前我们已经进行了大量的研究工作。

创建欺骗脚本

如果我们不熟悉AppleScript,或者不了解自Yosemite 10.10以来的macOS最新特性,我们可能会惊讶地发现,可以将Objective-C代码嵌入到脚本之中,并直接调用Cocoa和Foundation API。这意味着,我们就拥有了本地API的所有功能,例如:NSFileManager、NSWorkspace、NSString、NSArray等等。在下面的示例中,我使用的是商业版AppleScript编辑器,但它也有免费版本。与内置的Script Editor应用程序相比,AppleScript编辑器更加便于作为开发环境使用。

与其他任何脚本或编程语言一样,我们需要“导入”所需使用的框架,在AppleScript中是使用use关键字来完成的。我们可以将以下内容放在脚本的最开始部分:

3.jpg

这些既能充当快捷方式,也能作为AppleScript与ObjectiveC脚本之间的“桥梁”,同时还可以让我们以便捷的方式访问命名的API,如下所示。

接下来,我们编写一些“处理程序”(函数)来遍历PrivilegedHelper工具目录。在下图中,左边展示了我们将要编写的处理程序,右边是在我的计算机上返回的示例。

4.jpg

如我们所见,这个处理程序只是另一个处理程序enumerateFolderContents:的包装器,这个处理程序是我们从社区论坛借鉴而来的。我们来仔细分析一下它的代码,代码部分有一些复杂:

# adapted from a script by Christopher Stone
on enumerateFolderContents:aFolderPath
       set folderItemList to "" as text
       set nsPath to current application's NSString's stringWithString:aFolderPath
       --- Expand Tilde & Symlinks (if any exist) ---
       set nsPath to nsPath's stringByResolvingSymlinksInPath()
       
       --- Get the NSURL ---
       set folderNSURL to current application's |NSURL|'s fileURLWithPath:nsPath
       
       set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:folderNSURL includingPropertiesForKeys:{} options:((its NSDirectoryEnumerationSkipsPackageDescendants) + (get its NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
       set AppleScript's text item delimiters to linefeed
       try
              set folderItemList to ((theURLs's valueForKey:"path") as list) as text
       end try
       return folderItemList
end enumerateFolderContents:

现在,我们有了具有特权的帮助工具的列表,我们需要在路径中提取出文件名,因为我们希望在消息文本中使用这些名称来增强可信度。此外,我们可以从帮助工具的二进制文件中找到父应用程序,并将其显示给用户,同时还需要查找应用程序对应的图标。

这是我们执行第一个任务的方式,下图左侧是我们的代码,右侧展现了输出内容:

5.jpg

现在,我们已经有了目标,接下来的工作就是找到父应用程序。为此,我们将借鉴Erik Berglund的脚本并进行微调。

6.jpg

在上面的示例中,我们可以看到父应用程序的Bundle Identifier是“com.barebones.bbedit”。我们可以通过多种方式从字符串中提取标识符子字符串,比如我们可以使用awk之类的命令行使用工具(类似于Erik使用的方法),或者使用cut to slice字段。但是,出于效率的考虑,同时为了避免不必要地产生更多进程,我选用了Cocoa API的方法。请注意,无论使用哪种技术,标识符都不会始终出现在同一位置,并且可能不会以“com”开头。不过,在我们尝试的所有场景中,它都是紧随在“identifier”之后的。因此,我将其作为主要的分隔符。在这里,需要确保我们的代码考虑了一些特殊情况,由于空间不足,我在这里将省略错误检查的环节。

7.jpg

在上面的代码中,我使用Cocoa API首先在分隔符的任意一边拆分字符串。我们在第二个子字符串的开头部分找到实际的Bundle Identifier。在这里,需要注意后面的as text。在混合AppleScript与Objective C时,我们必须解决的一个难题时如何在NSString和AppleScript文本之间来回转换。

有了父应用程序的Bundle Identifier之后,借助NSWorkspace,我们可以找到父应用程序的路径。我们还将添加一个循环,以对PrivilegedHelperTools文件夹中的所有项目执行相同的操作。

8.jpg

请关注我在这里是如何将文本转换从bundleID变量中移走的,因为现在仍然需要NSString来进行NSWorkspace调用。文本转换将被延迟,直到在AppleScript调用中再次需要改字符串,该调用发生在repeat方法的末尾。

至此,我们现在有了每个具有特权的帮助工具的名称及其路径,以及Bundle Identifier和每个帮助工具父应用程序的路径。有了这些信息,我们就几乎拥有了授权请求所需的一切。接下来的最后一步,就是从每个父应用程序中获取应用程序图标。

获取父应用程序的图标图像

应用程序图标通常位于应用程序包的“Resources”(资源)文件夹中,并具有.icns扩展名。由于我们已经拥有了应用程序的路径,因此获取图标的过程应该非常简单。

在继续之前,我们首先需要为接下来的工作添加几个“帮助处理程序”,以保证代码的简洁。

10.jpg

此外,在脚本的最上方,我们定义了一些常量。目前,我们将其保留为纯文本格式,但在最终版本中我们可以借助各种方法对其进行混淆处理。

11.jpg

注意其中的defaultIconStr常量,它提供了我们的默认值。如果要查看其详细内容,可以使用以下命令来进行调用:

-- let's get the user name from Foundation framework:
       set userName to current application's NSUserName()
       display dialog hlprName & my makeChanges & return & my privString & userName & my allowThis default answer "" with title parentName default button "OK" with icon my software_update_icon as «class furl» with hidden answer


12.jpg

这个显示的图标还不错,但还有继续优化的空间,如果使用应用程序的实际图标,看起来会好很多。图标的名称被定义在应用程序的Info.plist中。我们可以添加另一个处理程序来对其进行抓取:

13.jpg

这是获取整理后的图标的代码:

14.jpg

下面是我们的脚本目前生成的一些示例:

15.jpg

16.jpg

总结

至此,我们产生的授权请求看起来非常具有说服力。在这些请求中,现在已经包含了一个真实的应用程序名称和一个进程名称。如果用户对它们进行深入调查,会发现它们都是合法的。此外,我们还有一个适当的密码字段,并且在消息文本中包含用户名称。在这一点上,并没有触发Mojave和Catalina版本中对AppleScript的增强安全机制,因此使用时也无需预先调查受害者计算机的版本信息。最重要的时,这一过程中完全不需要任何特权。

这样一来,我们就获得了想要的权限。在下一部分的文章中,我们将继续深入探究如何捕获用户输入的密码、如何在用户计算机上找到适当的时间来启动欺骗脚本,以及如何找到恰当的应用程序。我们将研究如何采用相同的技术来针对使用kexts和LaunchDaemons的其他特权应用程序。除此之外,我们将研究其他AppleScript技术,以构建具有两个文本字段的增强型对话框,敬请关注我们接下来的文章!

说明:本文中所提及的所有技术和操作过程都是完全合法的,且全程未利用任何漏洞,文章未涉及到任何漏洞的详细信息。仅供安全研究者与开发人员学习使用,不得用于非法用途。

  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务