XLL钓鱼战术
随着 Microsoft 近期公告 关于阻止源自互联网(电子邮件和网页下载)的文档中的宏,攻击者开始积极探索其他方式来实现用户驱动访问(UDA)。在寻找可行的网络钓鱼访问方法时,需要权衡和平衡几个因素:
这些是主要问题,当然还有更多。当你意识到这些因素相互叠加时,情况就变得更加复杂;例如,如果客户端有禁止下载可执行文件或 DLL 的 Web 代理,你可能需要将有效载荷放入容器(ZIP、ISO 等)中。这样做可能会在后续检测方面带来更多问题。更强的防御需要更复杂的技术组合来突破。
本文将设想一个虚构的目标组织;该组织采用了多项防御措施,包括电子邮件过滤规则、禁止下载某些文件类型、端点应用程序白名单以及使用 Microsoft Defender for Endpoint 作为 EDR 解决方案。
真实组织可能不采用这些措施中的任何一个,也可能采用部分甚至更多防御措施,这可能会简化或复杂化本研究中概述的技术。一如既往,了解你的目标。
XLL 是专门为 Microsoft Excel 制作的 DLL。在未经训练的人看来,它们看起来很普通 Excel 文档。

XLL 为 UDA 提供了非常有吸引力的选择,因为它们由 Microsoft Excel 执行,而 Excel 是客户端网络中非常常见的软件;额外的好处是,由于它们由 Excel 执行,我们的有效载荷几乎肯定能绕过应用程序白名单规则,因为受信任的应用程序(Excel)在执行它。XLL 可以用 C、C++ 或 C# 编写,这提供了比 VBA 宏更大的灵活性、能力和(理智性),进一步使其成为理想的选择。
当然,缺点是 XLL 的合法用途非常少,因此组织应该很容易通过电子邮件和网页下载来阻止该文件扩展名的下载。遗憾的是,许多组织落后多年,因此 XLL 在一段时间内仍将是可行的网络钓鱼方法。
有一系列不同的事件可用于在 XLL 内执行代码,其中最著名的是 xlAutoOpen。完整列表可在此处查看:

双击 XLL 后,用户会看到此界面:

这个单一的对话框就是用户与代码执行之间的唯一障碍;通过相当肤浅的社会工程,代码执行几乎可以保证。
必须记住的是,XLL 作为可执行文件,是架构特定的。这意味着你必须了解你的目标;目标组织使用的 Microsoft Office/Excel 版本(通常)将决定你需要为有效载荷构建的架构。
Office 版本有一个相当清晰的分界线,可以作为经验法则:
Office 2016 或更早版本:x86
Office 2019 或更新版本:x64
需要注意的是,每个产品都可以安装其他架构,但这些是默认安装的架构,在大多数情况下,这应该是决定你的 XLL 采用哪种架构的可靠方法。当然,根据网络钓鱼活动中使用的投递方法和诱饵,可以提供两种版本,并让受害者选择适合其系统的版本。
本研究期间构建的 XLL 有效载荷基于 edparcell 的 这个 项目。他的仓库有关于在 Visual Studio 中开始使用 XLL 的很好的说明,我以他的代码为起点开发了一个恶意的 XLL 文件。
与他仓库的一个显著区别是,如果你想创建自己的 XLL 项目,你需要下载 最新的 Excel SDK,然后按照之前链接的仓库中的说明操作,使用此版本而不是 README 中提到的 2010 版本的 SDK。
在 UDA 上下文中,有效载荷的投递是一个重要的考虑因素。我们将重点关注两种主要方法:
无论是通过附加文件还是包含指向可下载文件的网站链接,电子邮件都是 UDA 过程的关键部分。多年来,许多组织(和电子邮件提供商)已经成熟并制定了规则,以保护用户和组织免受恶意附件的侵害。具体效果会有所不同,但组织现在能够:
模糊测试组织的电子邮件规则可能是参与活动的重要部分,但必须始终小心,以免暴露红队行动正在进行中且正在主动收集信息。
出于本文的目的,将假定目标组织具有强大的电子邮件附件规则,阻止 XLL 有效载荷的投递。我们将转向并考虑网页投递。
在这种攻击向量中仍会使用电子邮件,但不会发送附件,而是发送指向网站的链接。控制允许下载文件类型的 Web 代理规则和网络缓解措施可能与电子邮件附件方面的规定不同。出于本文的目的,假定组织阻止从网页下载可执行文件(MZ 头部)。在这种情况下,值得探索 packers/containers。
前提是我们可能能够将可执行文件放入另一种文件类型中,并偷偷绕过组织的策略。一个主要的考虑因素是文件类型的原生支持;例如,7Z 文件无法在不安装第三方软件的情况下由 Windows 打开,因此它们不是很好的选择。像 ZIP、ISO 和 IMG 这样的格式是有吸引力的选择,因为它们被 Windows 原生支持,而且额外的好处是它们为受害者增加的步骤很少。
不幸的是,该组织阻止从网页下载 ISO 和 IMG;此外,由于他们采用了数据丢失防护(DLP),用户无法挂载外部存储设备,而 ISO 和 IMG 被视为此类设备。
幸运的是,尽管组织阻止下载带有 MZ 头部的文件,但它允许下载包含可执行文件的 zip 文件。这些 zip 文件会被主动扫描是否有恶意软件,包括提示用户输入受密码保护的 zip 文件的密码;但因为可执行文件被压缩了,所以它不会受到原本对 MZ 文件的全盘拒绝的限制。
选择 Zip 文件作为 XLL 有效载荷的容器是因为:
方便的是,在 Windows 上双击 ZIP 文件将在文件资源管理器中打开该 zip 文件:

不太方便的是,从压缩位置双击 XLL 文件会触发 Windows Defender;即使使用来自 edparcell 的原始项目(不包含任何恶意代码)也是如此。

查看 Windows Defender 警报,我们看到它只是一个通用的“Wacatac”警报:

但有些奇怪;它识别为恶意的文件位于 c:\users\user\Appdata\Local\Temp\Temp1_ZippedXLL.zip\,而不是我们双击的 C:\users\user\Downloads\ZippedXLL\。在 ProcessExplorer 中查看 Excel 实例显示,Excel 实际上是从 appdata\local\temp 运行 XLL,而不是来自它所在的 ZIP 文件:

这似乎是 ZIP 文件相关的一个问题,而不是 XLL 的问题。使用记事本从 zip 中打开 TXT 文件也会导致 TXT 文件被复制到 appdata\local\temp 并从那里打开。虽然从此位置打开文本文件没问题,但 Defender 似乎将此位置的任何实际代码执行识别为恶意。
如果用户从 ZIP 文件中提取 XLL 然后运行它,它将正常执行;但无法保证用户会这样做,而且如果他们没有提取,我们真的不能冒险触发 AV/EDR。此外,双击 ZIP 然后双击 XLL 要简单得多,受害者更倾向于完成这些简单操作,而不是费心提取 ZIP。
这个问题使我开始考虑与 XLL 不同的有效载荷类型;我开始探索 VSTO,即 Visual Studio 模板 for Office。我强烈建议你看看那篇文章。
VSTO 最终会调用一个 DLL,该 DLL 可以本地位于启动一切的 .XLSX 旁边,也可以通过 http/https 远程托管并由 .XLSX 下载。本地选项没有提供真正的优势(实际上有几个缺点,因为 VSTO 攻击涉及更多文件),而远程选项不幸地需要代码签名证书,或者远程位置必须是受信任的网络。由于没有有效的代码签名证书,VSTO 不能缓解我们的 XLL 有效载荷在此场景中遇到的任何问题。
我们似乎真的被逼到了角落。运行 XLL 本身没有问题,但由于组织策略,XLL 无法通过电子邮件附件或网页下载单独投递给受害者。XLL 需要打包在容器内,但由于 DLP,像 ISO、IMG 和 VHD 这样的格式不可行。受害者需要能够原生打开容器而无需安装第三方软件,这实际上只留下了 ZIP 作为选项;但如前所述,从压缩文件夹运行 XLL 会导致它被复制到 appdata\local\temp 并运行,从而触发 AV。
我花了很多时间头脑风暴和测试,深入 VSTO 的兔子洞,探索所有可能的选项,直到我最终决定尝试一些如此愚蠢以至于可能奏效的方法。
这次我创建了一个文件夹,将 XLL 放入其中,然后压缩了该文件夹:

点击进入文件夹会显示 XLL 文件:

双击 XLL 会显示来自 Excel 的加载项提示。请注意,XLL 仍然被复制到 appdata\local\temp,但由于我们创建的额外文件夹,多了一层:

点击“启用”会执行我们的代码,而不会触发 Defender:

不错!代码执行成功。然后呢?
让受害者下载并执行 XLL 所涉及的诱饵会根据组织和投递方法而有很大差异;主题可能包括员工薪资数据、基于技能组的薪酬计算器、项目信息、活动出席名单等。无论诱饵是什么,如果我们实际给受害者提供他们被承诺的东西,我们的攻击将有效得多。如果没有后续行动,受害者可能会起疑并向安全团队报告文档,这可能会迅速暴露攻击者并限制对目标系统的访问。
XLL 本身在我们的代码执行完毕后只会留下一个空白的 Excel 窗口;对我们来说,最好提供受害者正在寻找的 Excel 电子表格。
我们可以将 XLSX 作为字节数组嵌入到 XLL 中;当 XLL 执行时,它会将 XLSX 释放到磁盘上 XLL 旁边,然后打开它。我们将 XLSX 命名为与 XLL 相同,唯一的区别是扩展名。
鉴于我们的 XLL 是用 C 编写的,我们可以引入我之前关于 C 中的有效载荷能力 的帖子中的一些功能,即自删除。结合这两种技术,XLL 将从磁盘上被删除,而同名的 XLSX 会被放置在它的位置。对于不细心的眼睛来说,看起来 XLSX 从一开始就在那里。
不幸的是,XLL 被删除和 XLSX 被释放的位置是 appdata\temp\local 文件夹,而不是原始的 ZIP;为了解决这个问题,我们可以创建一个只包含 XLSX 的第二个 ZIP,并将其读入 XLL 中的字节数组。在执行时,除了上述操作外,XLL 可以尝试定位 c:\users\victim\Downloads\ 中的原始 ZIP 文件,并在释放仅包含 XLSX 的第二个 ZIP 之前将其删除。当然,如果用户将原始 ZIP 保存在不同的位置或名称下,这可能会失败,但在多数情况下,它应该会自动放入用户的下载文件夹。

此截图显示了下窗格中在 appdata\local\temp 中创建的 temp 文件夹,其中包含 XLL 和释放的 XLSX,而上窗格显示了最初从中打开 XLL 的文件资源管理器窗口。注意下窗格中 XLL 的大小为 0。这是因为它在执行过程中自删除了,但直到上窗格关闭,XLL 文件才从 appdata\local\temp 位置完全消失。即使受害者再次点击 XLL,它现在也是惰性的,并不真正存在。
类似地,一旦受害者在文件资源管理器中退出打开的 ZIP(通过关闭它或导航到不同的文件夹),如果他们再次点击 spreadsheet.zip,将会发现 test 文件夹包含 importantdoc.xlsx;因此,XLL 已从磁盘上存在的两个位置被移除,并由无害的 XLSX 替换。
此 GIF 演示了在 MDE 试用版 VM 上下载和执行 XLL 的过程。请注意,由于某些原因,此处 Excel 打开了两个实例;在我的家用电脑上只打开了一个,所以不太确定为什么不同。

一如既往,我们会问:“MDE 看到了什么?”
快速截图转储,以证明我确实在目标上执行了此操作并在 TestMachine11 上收到了 beacon 回连:



首先,零警报:

时间线/事件日志捕获了什么?

哎呀。说实话,我不知道键盘记录、加密和解密凭据的警报来自哪里,因为我的代码没有做这些。当这样列出时,我们的行为看起来确实可疑,但我再次要说明 MDE 在单个端点上收集的数据量有多大,更不用说一个组织可能接入 EDR 的数百、数千或数十万个端点。只要我们没有触发任何实际警报,我们可能就没事。
大多数人可能一直在等待的时刻,我提供了我开发的 XLL 运行器的代码示例,仅限于“行动技巧”部分讨论的内容。读者需要自己将代码放入 XLL 中,并与他们的运行器的其余部分一起实现。一如既往,不要造成伤害,获得钓鱼组织的许可,等等。
我提供了一个 源代码 程序,该程序将导入一个文件并生成可以复制到代码片段中定义的字节数组中的十六进制。将此用于你想要呈现给用户的 XLSX,以及包含该相同 XLSX 的文件夹的 ZIP 文件,并将它们存储到各自的字节数组中。使用以下命令编译此代码:``` gcc -o ingestfile ingestfile.c
我在使用 Kali 机器上的 MingW 编译我的 XLL 时遇到了一些问题,因此我想在这里发布命令:
**x64**```
x86_64-w64-mingw32-gcc snippet.c 2013_Office_System_Developer_Resources/Excel2013XLLSDK/LIB/x64/XLCALL32.LIB -o importantdoc.xll -s -Os -DUNICODE -shared -I 2013_Office_System_Developer_Resources/Excel2013XLLSDK/INCLUDE/
x86``` i686-w64-mingw32-gcc snippet.c 2013_Office_System_Developer_Resources/Excel2013XLLSDK/LIB/XLCALL32.LIB -o HelloWorldXll.xll -s -DUNICODE -Os -shared -I 2013_Office_System_Developer_Resources/Excel2013XLLSDK/INCLUDE/
编译完成后,你需要创建一个新文件夹并将XLL复制到该文件夹中。然后使用以下命令进行压缩:```
zip -r <myzipname>.zip <foldername>/
注意,为了使本文中概述的战术有效,你需要将代码片段中的某些变量与你命名的XLL和zip文件相匹配。
随着Office宏主导地位的终结,XLL为钓鱼攻击提供了一种有吸引力的选择。通过一些创意,它们可以与其他技术结合使用,以绕过组织和安全团队部署的多层防御。感谢阅读,希望你能学到有用的东西!