研究人员通过 IE11/Edge Legacy 和 MS Teams 在 Windows 10 上发现了一个驱动代码执行漏洞,该漏洞由 Windows 10/11 默认处理程序ms-officecmd: URI中的参数注入触发。

通过其他浏览器进行利用需要受害者接受一个不起眼的确认对话框,或者,恶意 URI 可以通过执行不安全 URL 处理的桌面应用程序传送。

 利用过程

代码执行由恶意网站触发,该网站执行 Javascript 重定向到精心制作的 ms-officecmd: URI(Microsoft Office UWP 应用程序用于启动其他 Office 桌面应用程序的方案)。研究人员利用 URI 处理程序中的参数注入漏洞并绕过 Electron 中的安全措施,通过 Microsoft Teams Electron 应用程序的 --gpu-launcher 参数注入任意操作系统命令。

通过 MS Edge 在 Windows 10 上驱动 RCE的视频请点此。

这是上面视频中使用的精心制作的 ms-officecmd: URI(注意,JSON进行了缩进):

除Internet Explorer和Microsoft Edge Legacy之外的浏览器在打开恶意URI之前会显示一个相当不显眼的确认对话框:

显示 IE 和 Edge Legacy 中缺少的确认对话框的不同浏览器

作为通过恶意网站进行利用的替代方法,精心制作的 ms-officecmd: URI 也可以通过执行不安全 URL 处理的桌面应用程序传送。

此特定漏洞利用的先决条件是已安装 Microsoft Teams 但未运行。在以下部分中,研究人员还将展示如何在MS Teams 帮助的情况下以其他方式滥用方案和参数注入。

虽然在进行本研究时 Windows 11 尚未发布,但它也仍然受到 ms-officecmd: URI 处理程序中相同参数注入漏洞的影响。

 改进恶意 URI 攻击场景

2021 年 1 月,研究人员花了一些时间分析流行的桌面应用程序如何处理用户提供的 URI,并在其中发现了代码执行漏洞。

为了展示研究人员在 Windows 上的发现的利用他们主要利用文件相关方案(nfs、dav、file 等)以及托管在网上可访问文件共享上的可执行文件/jar 文件。这些有效载荷的一个警告是,它们要么需要安装 Java,要么需要一个对话框来运行要确认的可执行文件。

在此过程中,研究人员还在 WinSCP 的 URI 处理中发现了一个代码执行漏洞。WinSCP实际上是在Windows上处理各种URI方案的标准,但它并没有预装在操作系统中。第三方URI处理程序的漏洞并不新鲜,之前的示例包括:

Steam 中的代码执行:URI 处理程序(2012) ;

影响注册自定义协议的 Electron 应用程序的代码执行 (CVE-2018-1000006)];

teamviewer10 中的代码执行:URI 处理程序 (CVE-2020-13699);

研究人员希望通过在 Windows 预装的 URI 处理程序中找到代码执行漏洞,进一步改进基于恶意 URI 的攻击场景。

 在Windows 10中枚举URI处理程序

Windows 10提供了大量与不同操作系统功能或其他 Microsoft 软件相关的自定义 URI 处理程序。

出于研究目的,查找已注册 URI 处理程序的一种非常方便的方法是在注册表中重复搜索 'URL Protocol' :

在 Windows 注册表中查找 URI 处理程序

Computer\HKEY_CLASSES_ROOT\* 中的任何命中都意味着包含文件夹的名称对应于已注册 URI 处理程序的方案。注册表还包含更多信息,例如用于调用相应处理程序的 shell 命令。一种非常简单且更实用的方法来帮助找出与该方案相关的内容是将其输入到浏览器地址栏中,然后输入 :,最后按 Enter:

通过 Edge 的 `calculator:` 方案打开 calc.exe的视频请点此。

 ms-officecmd:过于复杂

ms-officecmd: 该方案因其有名称而立即引起了研究人员的注意:MS Office 是一个非常复杂的应用程序套件,具有许多遗留功能和悠久的可利用历史。最重要的是,该方案以'command'的缩写结尾,这表明注入的复杂性和潜力更大。

当研究人员开始使用它时,发现一个名为 LocalBridge.exe 的可执行文件,它会短暂运行,,但不会产生明显的外部影响。为了更深入地了解发生了什么,研究人员查看了 Windows 事件日志,其中包含一些非常有用的信息:

.NET JsonReaderException 通过打开 URI `ms-officecmd:invalid` 被触发

当打开一个由空的、有效的JSON有效载荷ms-officecmd:{}组成的URI时,没有发生同样的异常,这为研究人员提供了关于有效URI结构的第一个提示。

观察到 URI 处理程序中的 JSON 解析最终证实 ms-officecmd: URI 有可能做非常复杂的事情,因此有必要弄清其功能。

反转 LocalBridge.exe 和 AppBridge.dll

为了了解更多信息,研究人员决定从反编译 LocalBridge.exe 开始:

`LocalBridge.exe` 的反编译源:URI 验证和 `LaunchOfficeAppValidated` 调用 (dotPeek)

C# 代码包含有关有效 JSON 有效载荷结构的更多信息:

不幸的是,这并没有引起 LocalBridge.exe 的任何可观察到的行为。进一步分析AppBridge.dll,因为它包含LaunchOfficeAppValidated方法,JSON有效载荷最终会被传递给:

`LocalBridge.exe` 的反编译源:从 `AppBridge.dll` (dotPeek) 导入的 `LaunchOfficeAppValidated`

研究人员通过反汇编原有AppBridge.dll 库提取了更多潜在的 JSON 属性名称,但如何使用它们并不是很明显。

`AppBridge.dll`:相关的 unicode 字符串

 调试 Office UWP 应用 (Electron PWA)

当对LocalBridge.exe/AppBridge.dll的分析没有迅速产生预期的结果时,研究人员同时采用了另一种方法:与其剖析处理ms-officecmd: uri的应用程序,不如试着检查生成这种uri的应用程序。

虽然研究人员不确定哪些应用程序会这样做,但之前偶然发现的 Office UWP 应用程序可能是一个有用的应用程序:

该应用程序可以通过自定义方案 ms-officeapp: 打开,它看起来与研究人员研究的主题 ms-officecmd 非常相似:

该应用程序的行为与 https://www.office.com/ 上的 Office365 网络界面几乎相同,不同之处在于它允许打开一些无法从网络打开的桌面应用程序

Office UWP 应用预装在 Windows 10 上

根据经验,每当Office UWP应用程序触发一个Office桌面应用程序被打开时,就在内部使用ms-officecmd:方案。使用 Microsoft 自己的“Edge DevTools Preview”应用程序,研究人员能够进入进程并调试 Office UWP 应用程序。

Microsoft Edge DevTools Preview(右)提供 Office UWP 应用(左)作为调试目标

获取研究人员想要的信息既快速又简单:

执行一个全局源代码搜索(ctrl + shift + f)来找到scheme关键字'ms-officecmd'的出现:唯一找到的出现是launchProtocol常量的定义;

执行另一个搜索来发现launchProtocol常量的用法:第一个命中是在launchViaProtocol方法中发现的;

在launchViaProtocol中添加一个断点并尝试触发它:点击左侧栏的Outlook图标实现了这一点。

 从局部变量中提取 JSON 载荷结构

Office UWP 应用:`launchProtocol` 常量定义(Edge DevTools 预览版)

Office UWP 应用:`ms-officecmd:` 从局部变量 `n` 中提取的 JSON 载荷(Edge DevTools 预览版)

恢复 JSON 有效载荷的更快替代方法是使用 Microsoft Sysinternals Process Monitor 工具记录与 LocalBridge.exe 关联的 Process Create 事件:

`ms-officecmd:` 进程监视器显示的 JSON 有效载荷

 ms-officecmd:基本的 JSON 载荷结构

使用提取的 JSON 载荷,就可以通过 ms-officecmd: URI 打开 Office 桌面应用程序。具体来说,从 Office UWP 应用中提取的载荷可用于打开 Outlook:

在随后的测试中,很明显有两个属性可以被操纵,产生立即可见的效果:

appId:要打开的Office桌面应用程序;

filename:要在指定应用程序中打开的文件的文件路径或URL;

name 和 command 属性被验证并以较低的优先级处理;

在安装了基本 Office 的计算机上,研究人员列举了以下 appId 映射:

  • 1: Access
  • 2: Excel
  • 5: Teams
  • 6: Skype for Business
  • 7: One驱动
  • 8: Outlook
  • 10: PowerPoint
  • 12: Publisher
  • 14: Word
  • 18: OneNote
  • 21: Skype

 Outlook 网络钓鱼问题

第一个值得注意的发现是,当在filename属性中提供 http(s)URL 时,Outlook 将在 IE11 驱动的嵌入式 web 视图中呈现相应的网页。没有说明网页的来源,甚至没有提供显示内容源自外部网页的事实。这种行为可能会被滥用来发起非常可信的网络钓鱼攻击,尤其是因为 mailto: 链接根据本地配置预计会打开用户的电子邮件程序:

使用 `ms-officecmd:` 和 Outlook 进行网络钓鱼攻击:Outlook 窗口内显示的登录表单是攻击者控制的网页,相关视频请点此。

 Outlook 代码执行问题

Outlook 的意外打开行为也可能被滥用,以通过更多用户交互实现代码执行。虽然 Outlook 不允许 file:// URL,但允许使用 C:// "url scheme" ,然后作为本地路径的驱动号。此外,我们在AppBridge.dll中添加了一个绕过文件扩展名检查的尾随/,但稍后在打开可执行文件时将被忽略。

这个 PoC 要求用户确认一个额外的警告对话框,但研究人员认为上下文足以误导一些更高级的用户接受:

使用 `ms-officecmd:` 和 Outlook 从 Chrome 进行用户交互的 RCE 攻击,详细视频请点此。

以下是点击恶意网页上的链接时发生的情况:

通过动态添加iframe指向outlook.exe(在本文中,这是一个重命名为“PuTTY”的可执行文件),一个名为outlook.exe的恶意可执行文件被保存到受害者的下载文件夹中。

看似无害的mailto: link目标被替换为一个恶意的ms-officecmd: URI,它在其filename属性中引用下载的可执行文件(注意左下角的悬浮链接预览);

用户确认“Open LocalBridge?”对话框(不是明确的安全警告);

当 Outlook 启动时,它会显示一个关于打开潜在不安全超链接的警告对话框。用户确认打开本地“outlook.exe”文件,因为他们希望outlook被打开;

执行下载的文件(弹出PuTTY窗口);

 filename属性参数注入

上面显示的问题滥用了filename属性,因为它提供了仅在Outlook应用程序上下文中未预料到的和错误处理的值,但在ms-officecmd: URI处理程序的更抽象的上下文中是完全有效和预期的:除了具有多种不同文件扩展名的本地文件路径外,大多数Office应用程序还允许通过http(s)url直接打开托管在 Web 上的文档,就像Microsoft SharePoint/OneDrive中的文件一样。

下一个发现是通过攻击 URI 处理程序本身处理filename属性的方式,进一步推动了滥用的可能性。即使没有完全详细了解 AppBridge.dll 的内部工作原理,也可以假设,为了使用指定参数打开指定的 Office 应用程序,URI 处理程序最终要么生成并执行 shell 命令,要么运行它的可执行文件直接。在任何情况下,攻击者控制的filename属性都需要作为 shell 命令的一部分或参数传递。当研究人员尝试使用常见的命令和参数注入技术时,研究人员发现可以使用简单的 "(双引号+空格)序列来突破filename规范。

此参数注入代表了此处概述的发现的核心中最重要的问题。在研究人员开始实际利用之前,这里有一个视频演示了最基本的参数注入:

使用 `filename` 参数注入来注入 `/q` 开关:注意打开第二个 URI 时没有蓝色启动(加载)屏幕,详细视频请点此。

这是视频中使用的 URI(需要对引号进行转义以免破坏 JSON):

 加载恶意 Word/Excel 插件

在发现可以将参数注入 Office 应用程序的启动命令后,下一步自然是检查哪些类型的参数可供研究人员使用。在已记录的 Microsoft Office 产品命令行开关中,与在启动时加载插件有关的命令行开关似乎最有希望。

研究人员试验了以下插件类型:

普通 .dll 和 .wll 文件;

VSTO 插件;

“Office”(网络)插件;

不幸的是,研究人员无法使应用程序在启动时正确加载任何插件。

尝试使用“-l”开关加载 Word 插件失败,因为应用程序似乎将其解释为要打开的文档文件

 Teams MITM,使用 --host-rules 进行身份验证泄漏

虽然研究人员对以文档为中心的 Office 应用程序的参数注入实验并没有产生更多对现实世界攻击者很感兴趣的发现,但还有另一组应用程序显示了巨大潜力:Microsoft Teams 和 Skype 是基于Electron 框架的,因此配备了大量有用的 Electron 命令行参数和 Node.js 命令行参数。

具有滥用潜力是 --host-rules,此参数可用于重新映射 IP 地址和主机名,从而将应用程序的所有相关网络流量定向到所选目标。使用新域作为映射目标时,只要为新域正确设置了 TLS,就不会出现 TLS 错误。通过添加 --ignore-certificate-errors 开关,甚至不需要这样做。借助反向代理,甚至只是侦听 Web 服务器,攻击者可以提取发送到 Microsoft Teams 后端服务的所有敏感信息,包括身份验证令牌和消息。还可以利用反向代理来修改 API 响应,并向受害者冒充任何MS Teams 用户。

当研究人员试图制作一个有效的有效载荷以注入这些参数时,它们不得不克服另外两个障碍:

作为对关键 CVE-2018-1000006 的修复,Electron 更改了他们的命令行解析逻辑,以在 URI 之后删除其他参数。检查源代码,研究人员发现了 1-letter URI 方案的异常,以跳过对包含驱动号(即 C:/)的 Windows 文件路径的过滤。这允许研究人员在像 a:/b/ 这样的虚假filename前缀之后注入 Electron 参数,这是被Electron和AppBridge.dll所接受的。

MS Teams有时不会为包含的filename参数启动.(句号)字符由于在AppBridge.dll中检查文件扩展名。在下面的视频中,通过将目标IP地址3.64.176.207转换为其整数格式54571215来绕过此检查。

使用注入的 `--host-rules` 和 `--ignore-certificate-errors` 参数将 MS Teams https 流量重定向到研究人员自己的服务器,详细视频请点此。

请注意,在这个演示视频中,请求没有转发到Team的实际后端,从而导致连接错误。

这是视频中使用的 URI:

通过 --inspect 调试器从本地网络执行 Teams/Skype 代码

另一个有希望的参数是 Node.js --inspect 参数,它可用于调试 Node.js Javascript 环境。该参数指定可用于连接调试器的网络接口和端口号。出于安全原因,默认情况下只能通过本地接口 127.0.0.1 进行调试。在下面的视频中,研究人员通过 --inspect="0.0.0.0:28966" 开关覆盖了该设置,以便在端口 28966 上为任何网络接口接受调试器连接。连接调试器后,研究人员使用标准的 Node.js 库来执行命令:require("child_process").exec("")

再次制作有效的有效载荷需要一些技巧:

由于Skype这样打开时filename参数的处理方式,所以在注入其他参数之前,需要在假filename后面多加一个"字符

指定侦听接口时,不接受 IP 地址整数格式,迫使研究人员将 .人物。因此,这一次,研究人员通过在恶意filename有效载荷的末尾添加一个 / 字符来绕过 AppBridge.dll 中的文件扩展名检查。

通过单击 VM 内的恶意链接并将调试器从主机系统连接到 Skype 进程来展示本地网络漏洞,视频请点此。

这是视频中使用的 URI:

请注意,对于易受攻击的设置,此攻击还可以与例如 DNS 重新绑定或(最近改进的)NAT Slipstreaming 技术相结合,以通过浏览器实现 RCE,而无需本地网络访问。

通过 --inspect 调试器和 MITM 与 SOP 绕过团队代码执行;

研究人员实际上还没有确认这个潜在的漏洞可以运行,但无论如何都想分享它的想法,因为它的设置很有趣。这个想法是将上面部分中的 --host-rules 和 --inspect 开关与 --disable-web-security Chromium 开关结合起来,这应该允许研究人员利用它们对 Chromium Javascript 上下文的控制来连接到节点.js 调试器并执行任意命令:

1.MS Teams 是通过恶意网站启动的,并注入了以下参数:

  • --host-rules="MAP
  • --ignore-certificate-errors
  • --inspect=1337
  • --disable-web-security

2.在启动期间,位于

3.Electron Chromium 浏览器中的恶意Javascript 请求位于 http://127.0.0.1:1337/json/list 的 Node.js 调试器元数据终端,以检索调试器连接所需的

4.Electron Chromium 浏览器中的恶意 Javascript 连接到位于 ws://127.0.0.1:1337/

 通过 --gpu-launcher 命令注入执行团队代码

根据研究人员在开始向 Microsoft 提交报告之前所做的最后一项发现,他们终于通过恶意 ms-officecmd: URI 实现了任意代码执行。此 PoC 的先决条件是安装了 MS Teams 但未运行。

研究人员的恶意载荷基于 CVE-2018-1000006 的漏洞利用,它利用 --gpu-launcher 参数注入在 Electron 应用程序启动时执行的任意命令。为了利用研究人员的参数注入和 MS Teams 进行漏洞利用,研究人员需要:

1.使用 1 个字符的 URI 方案启动filename参数以通过 AppBridge.dll 验证,但也不会遇到针对 CVE-2018-1000006 的 Electron 修复(Electron 仍然允许在 Windows filename之后添加其他参数,例如“C:”);

2.注入额外的 --disable-gpu-sandbox 参数;

3.绕过AppBridge.dll中的文件扩展名检查.字符或在恶意filename值后附加/

4.添加一个shell指令,它可以用来将诸如&&这样的命令链在注入命令的末尾,以保持有效的语法。

通过 MS Edge 和 Teams 与用户交互的任意代码执行视频请点此。

有效载荷可能如下所示:

Skype 预装在 Windows 10 上,可以通过在启动命令中添加 --secondary 参数来并行启动多个 Skype 实例。因此,如果发现有效载荷通过 Skype 应用程序利用此问题,它应该可以在没有任何先决条件的情况下在默认的 Windows 10 安装上运行。研究人员试图为 Skype 找到一个有效载荷,但没有成功。当发现 Skype 易受 CVE-2018-1000006 攻击时,它似乎有可能实施了额外的安全措施。

 通过 --gpu-launcher 命令注入对 IE11/Edge Legacy 进行驱动利用

现在研究人员开始为 Microsoft 编写错误报告,当他们提交报告时,研究人员注意到 MSRC 报告进程包括一个强制性的下拉选项,用于指定是否可以在最新的 Windows 版本的“Windows Insider Dev Channel”上重现报告的漏洞。

MSRC 报告进程询问“此是否在 Windows Insider Dev Channel 上重现?”

令研究人员惊讶的是,该漏洞不仅有效,而且通过简单地添加一些点击恶意链接的 JavaScript,预装的 Internet Explorer 11 和MS Edge (现已过时的)的“旧版”版本可能会被滥用以触发代码执行除了浏览恶意网站之外,没有任何用户交互。由于研究人员最初的动机是改进他们之前涉及打开任意 URI 的桌面应用程序的攻击场景,因此并没有过多考虑浏览器利用问题,只是假设所有现代浏览器在处理诸如ms-officecmd。事实证明,该假设是错误的,正如 MS Edge Legacy 所证明的那样。通过 MS Edge 在 Windows 10 上驱动 RCE的视频请点此。

这是上面视频中使用的有效载荷:

有了这个视频证据,研究人员提交了他们的报告。

参考及来源:

https://positive.security/blog/ms-officecmd-rce