获取对话框当前cfont_macOS红蓝对抗:如何QP具有特权的帮助工具以获取root权限...

概述

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

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

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

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

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

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

4、打开原始Socket;

5、管理进程;

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

7、更改系统设置;

8、加载内核扩展。

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

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

10de37b2d04e379f7af060c68365a82a.png

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

/Library/PrivilegedHelperTools

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

BBEdit;

Carbon Copy Cloner;

Pacifist。

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

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

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

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

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

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

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

98f829ad134a51928030223f9b6565bd.png

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

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

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

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

创建欺骗脚本

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

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

406c35fbee157f05193d3d85ed121ae4.png

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

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

6d9d6fa3fef7af2e4b3606bc6f7ade7e.png

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

# adapted from a script by Christopher Stoneon 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 folderItemListend enumerateFolderContents:

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

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

6e9a498297a28e92e9422d96e4f33b99.png

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

0afeff67df06717adf7b2b258e75abd3.png

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

c93dece687462b1a808cdb6e1d673465.png

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

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

15c9540746965cab287e9cc74fd02e47.png

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

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

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

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

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

f86afeb5b24ff065f1252b063b3c5c45.png

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

70ed9ee1795792f9965145c03bfba837.png

注意其中的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
ffd37d871783b2e0bec5dd573b86b895.png

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

4635257da53adc3a530aa7a0abf74678.png

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

ed2d4fb08a2040035fca58dd43afce55.png

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

a5de47673dfda05c6d1742fbb2c6fbbf.png
66428830d5e30145b5b286f791b102e6.png

总结

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

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

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

如果你对macOS对抗感兴趣,可以点击下方扩展链接,查看更多相关内容。

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值