需要云计算吗? 即刻开始体验

旧框架难以用作新用途:Windows UI Automation 面临的危险

Tomer Peled

寫於

Tomer Peled

December 11, 2024

Tomer Peled

寫於

Tomer Peled

Tomer Peled 是 Akamai 的安全研究员。他的日常研究工作主要涉及漏洞和操作系统内部结构等方面。闲暇时,他喜欢烹饪美食、练马伽术以及玩 PC 游戏。

这项分析揭示了一个令人遗憾的案例,即原本出于善意而开发的技术如何遭劫持并用于恶意目的。
这项分析揭示了一个令人遗憾的案例,即原本出于善意而开发的技术如何遭劫持并用于恶意目的。

编辑和评论补充:Tricia Howard

执行摘要

  • Akamai 安全研究员 Tomer Peled 探索了利用和滥用 Microsoft UI Automation 框架的新方法,并发现了一种可以躲避端点检测和响应 (EDR) 的攻击手段。

  • 要利用这一手段,必须说服用户运行一个使用 UI Automation 的程序。这可能会引发隐秘命令的执行,进而收集敏感数据,将浏览器重定向到钓鱼网站等。 

  • 多种方法,包括 EDR 在内,都难以有效检测出这种手段。我们测试了多种 EDR 技术来抵御这一手段,但遗憾的是,它们均未能检测到任何恶意活动。  

  • 这一手段能够在运行 XP 操作系统及更高版本的任何一个 Windows 端点上发动攻击

  • 在本博文中,我们详细阐述了如何利用(滥用)UI Automation 框架(包括利用此框架可能进行的攻击),并针对我们讨论的每一种滥用途径,提供了概念验证 (PoC)。我们同时还提供了检测和抵御方案。

前言

从事写作工作的人偏爱听写和语法检查软件,而从事安全研究工作的人则喜欢拆解这些软件,然后将过程与发现记录下来。所以,在连续数月看到这些写作辅助软件的广告后,我们决定动手探索一番,看看能发现些什么。

具体来说,我们想了解一个应用程序如何远程操纵另一个应用程序的用户界面 (UI)。我们对研究结果的震惊程度,与得知仍有用户在使用 XP 系统的震惊程度不相上下:它由一个名为 UI Automation 框架的非常古老的框架来处理。

这个框架最初设计于 Windows XP 时代,旨在帮助残障人士更便捷地使用电脑。它被赋予了高级权限,以帮助执行诸如文本放大、文本朗读,以及(在特定情况下)模拟点击等多种辅助功能。为了实现这一目标,UI Automation 需要具备对屏幕上几乎所有 UI 元素的操控权限,考虑到其设计初衷这是完全合理的:该技术仅执行被明确指示的操作,而不会执行任何未被授权的操作。

我们从这里开始着手研究,旨在揭示攻击者滥用 UI Automation 可能带来的影响。

我们发现攻击者可以滥用 UI Automation 来窃取数据、操纵互联网浏览、执行命令,甚至从 WhatsApp 或 Slack 等聊天应用程序中读写消息。我们测试的每个 EDR 供应商都对所有这些活动毫无察觉

本博文将全面介绍您需知晓的关于此框架的所有信息,涵盖其工作原理和功能被滥用的各种方式等等。最后,我们将为蓝队队员提供检测和 抵御 方案。

通过 COM 与 UI Automation 交互

为了与其他应用程序中的元素进行交互,UI Automation 框架 (UIA) 将组件对象模型 (COM) 用作其进程间通信 (IPC) 机制。

COM 是 Microsoft 设计的一个框架,可支持不同程序相互通信, 不论它们是用何种语言编写或编译的。利用 COM 框架,开发人员可以创建名为 COM 对象的组件。这些对象在 Windows 端点上注册,注册信息包括它们的名称、通用唯一标识符 (UUID),以及一个含有逻辑和其他可配置值的二进制文件。

为了与 UIA 进行交互,用户可以调用“CoCreateInstance”来创建其 COM 对象。在调用此函数时,需指定 CUIAutomation 类 UUID 和 UIAutomation 接口 UUID,如下表所示。

CUIAutomation UUID

ff48dba4-60ef-4201-aa87-54103eef594e

UIAutomation 接口 UUID

30cbe57d-d9d0-452a-ab13-7ac5ac4825ee

在创建 COM 对象期间,系统将加载注册表中指定的 DLL,在本例中为“UIAutomationCore.dll”。

这听起来熟悉吗?细心的读者可能已经注意到,上述内容与我们对 MS-RPC所开展的广泛研究颇为相似。COM 以 RPC 为基础,因此它们存在相似之处。

UI Automation——Hello World

在深入探讨攻击者可能滥用此框架的方式之前, 您或许需要先回顾一下如何(通过 C++)与 UIA 进行常规交互。这将为您提供背景信息,帮助您理解此框架在实施过程中出现了哪些问题。您可以在我们的 GitHub上查看如何与 UIA 进行交互。

创建 UIA 对象后,其 DLL 将加载到用户的应用程序中,以及具有任何 UI 元素的所有其他进程中

在我们添加事件处理程序来监控远程进程的 UI 变化之前,不会发生其他任何操作。以下示例显示了如何设置处理程序来监控当前为用户打开的工具提示中的任何变化。

  ppAutomation->AddAutomationEventHandler(UIA_ToolTipOpenedEventId, pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationEventHandler*)whatsappEventHandler);

完成此操作后,UIA 将在远程进程上打开一个“服务器”来与我们的应用程序通信(图 1)。它们之间传输的数据是远程进程中所有 UI 元素的相关信息。

完成此操作后,UIA 将在远程进程上打开一个“服务器”来与我们的应用程序通信(图 1)。 图 1:加载到包含 UI 元素的所有进程中的 UIA dll

根据 Microsoft 的文档,以下处理程序原型是 UIA 期望的标准处理程序:

  HRESULT HandleAutomationEvent(
  [in] IUIAutomationElement *sender,
  [in] EVENTID              eventId
);

我们可以通过在事件处理程序中调用“sender.get_CurrentName”函数,来准确识别被置于 UI 前端的应用程序(无论是通过打开它还是以其他方式)。现在我们知道了哪个应用程序被带到了前端,接下来可以尝试对其进行读/写操作。

为此,我们需要通过遍历所有元素(这些元素是 sender 元素的后代)来找到我们想要读/写的元素,在此过程中,我们可以读取其 UI 值、更改文本值,或者检索可调用元素并调用其“Invoke”函数(图 2)。

为此,我们需要通过遍历所有元素(这些元素是 sender 元素的后代)来找到我们想要读/写的元素,在此过程中,我们可以读取其 UI 值、更改文本值,或者检索可调用元素并调用其“Invoke”函数(图 2)。
图 2:在更高层面查找并操纵元素的进程

滥用 UI Automation 从事恶意活动

在上一节中,我们讨论了滥用 UIA 的 方式 ,现在我们将讨论这些滥用行为可能招致的恶意活动。为了展示这类活动,举例说明是最直接有效的方法,我们准备了三个例子:

  1. 读取和写入消息
  2. 窃取敏感数据 
  3. 执行命令

读取和写入消息

每个消息传递应用程序都有一个图形化用户界面 (GUI),其中包含我们可以使用 UIA 访问的不同类型的 UI 元素。图 3 是 Slack 的 GUI 示例,您对它应该很熟悉。

 图 3 是 Slack 的 GUI 示例,您对它应该很熟悉。 图 3:Slack 的典型外观

在 GUI 中可进行的操作丰富多样,从选择对话(在后台通过按钮实施)到读取消息(文本块),为我们提供了丰富的交互元素。

一旦攻击者能够“连接”到此类应用程序的 UI 窗口,他们就可以(通过 UI 按钮元素)模拟点击要进行的对话并进入对话。由此,他们可以选择读取对话内容并窃取数据,和/或找到负责写入消息的 UI 元素,更改其 TextArea 元素中的文本值,并模拟点击发送按钮。

当然,这类操纵也会在屏幕上反映出来,让攻击者不那么容易得逞。一种更为隐秘的方式是在当前已开启的对话中执行只读操作,通过这种方式在更长的周期内持续收集数据(图 4)。

一种更为隐秘的方式是在当前已开启的对话中执行只读操作,通过这种方式在更长的周期内持续收集数据(图 4)。 图 4:从 Slack 读取信息

除了采取被动方式外,另一种保持隐蔽性的方案是利用 UIA 的缓存机制。。除了屏幕上当前显示的我们可以与之交互的 UI 元素外,还有更多元素是提前加载的并放置在缓存中。我们也可以与这些元素进行交互,例如阅读屏幕上未显示的消息,甚至设置文本框并发送消息,且这些活动不会在屏幕上反映出来。

尽管在本博文发布之前我们无法进行验证,但缓存机制可能也允许我们在计算机处于锁定状态时与这些元素进行交互,这样我们便能够随心所欲地进行交互,并且用户完全不知情。

窃取敏感数据

我们想到的利用(滥用)UIA 的一种更具破坏性的方式是窃取信用卡信息。

当用户访问线上商家平台后,攻击者可以通过设置处理程序,以编程方式监听 UI 元素的变化。一旦发生了变化(即输入了信用卡信息),攻击者就可以从 UI 元素中检索文本以便稍后提取(图 5)。

 一旦发生了变化(即输入了信用卡信息),攻击者就可以从 UI 元素中检索文本以便稍后提取(图 5)。 图 5:从浏览器收集信用卡信息

执行命令

另一种在浏览器中常见的攻击手段是网络钓鱼和浏览器重定向。

通过过滤 firefox/chrome/edge 的 UI 窗口,攻击者可以轻松搜索其 搜索栏 UI 元素,并将元素值设置为他们需要的值,然后模拟点击 (图 6)。为了让这一操作更加隐蔽,他们会等到当前显示的网页刷新或更改时再行动,这样一来,跳转到另一个网站的行为就不会那么容易被察觉。

由此,攻击者就可以将用户重定向到他们掌控的恶意站点。从那里几乎可以进行各种攻击:浏览器漏洞利用攻击(例如,使用 浏览器入侵框架 [BeEF])、过路式攻击、伪装合法网站以进行网络钓鱼或凭证收集等等。

由此,攻击者就可以将用户重定向到他们掌控的恶意站点。从那里几乎可以进行各种攻击:浏览器漏洞利用攻击(例如,使用浏览器入侵框架 [BeEF])、过路式攻击、伪装合法网站以进行网络钓鱼或凭证收集等等。 图 6:将用户重定向至 BeEF

UI Automation 的潜在影响

我们在前几节讨论的攻击方式已经存在了几十年,并且实现方式各异,而大多数防御工具都已经能够检测并应对这些攻击。

然而,上面讨论的所有攻击均被视为 UI Automation 的一项 功能 。这又回到了该应用程序的初衷:为了使用它,那些权限级别是必须要存在的。正因如此,UIA 才能绕过 Defender——应用程序不会发现任何异常。事实上,可能是出于同样的原因,我们测试的 EDR 都没有发现这些行为是恶意的。如果某个事物被视为一项功能而非错误,机器的逻辑将遵循该功能来运作。

这一框架可能为攻击者提供巨大利益,因此,我们认为深入了解它是应对这一攻击途径的关键所在。

进一步研究

通过 DCOM 访问 UIA

分布式 COM (DCOM) 是机器之间远程调用 COM 对象的一种方法。从理论上讲,可以通过 DCOM 远程访问 UIA,在无需网络钓鱼或本地访问权限的情况下,实施我们之前讨论过的各类攻击。

在我们的分析中,我们意识到 UIA 的 COM 对象默认情况下并未配置为允许 DCOM。这大大降低了攻击的可能性,除非出现配置错误。

虽然 UIA 本身不能通过 DCOM 直接访问,但我们确实发现了一些相关内容:UIAutomationCrossBitnessHook COM/DCOM 对象。远程激活和执行这个对象不需要权限。

通过逆向解析其 DLL,我们发现它的接口包含两个功能:一个用于设置 UI 管理器,另一个用于取消设置。它似乎没有任何其他远程功能,因此我们无法利用它来读取或写入数据,但未来它可能会成为一个很好的研究目标。

UIA 命名管道

在前文中,我们提到 UIA 会在远程进程上打开一个“服务器”。在后台,这些服务器与客户端是通过命名管道来实现的。命名约定由常量字符串 UIA_PIPE,后跟进程 ID 和一些其他标识符组成(图 7)。

命名约定由常量字符串 UIA_PIPE,后跟进程 ID 和一些其他标识符组成(图 7)。 图 7:攻击者应用程序中的 UI 命名管道

而可怕之处就在于此:命名管道可以接受远程连接。这种情况非常危险,因为这意味着攻击者可能会通过网络操纵 UI 元素。当我们尝试从远程服务器进行连接时,我们遇到了 ACCESS_DENIED 错误。

这是因为 Microsoft 在创建命名管道时设置了标志 PIPE_REJECT_REMOTE_CLIENTS 。这意味着我们无法通过这些管道远程访问 UIA,但它们在本地仍然可用。可以枚举出这些管道(无需猜测进程 ID 或标识符)并进行访问,这可能会为某种权限提升攻击或仿冒提供便利,但这并不是本分析的一部分。

检测/抵御

Microsoft 认识到 此框架不应与更高权限的应用程序交互。因此,默认情况下,使用 UI Automation 框架的应用程序将以中等信任级别运行,且不允许访问更高权限的进程。可以使用一个经签名验证的应用程序来绕过此限制,该应用程序的清单文件中包含设置为 true 的键 requestedExecutionLevel.uiAccess

  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
   <security>
     <requestedPrivileges>
      <requestedExecutionLevel
        level="highestAvailable"
        uiAccess="true" />
    </requestedPrivileges>
   </security>
  </trustInfo>

至于检测,管理员可以监视 UIAutomationCore.dll的使用情况。如果它被加载到以前未知的进程中,则应该引起合理的关注。

同样,网络管理员可以监视 UIA 在端点上打开的命名管道,作为其使用情况的另一个指标,您可以使用以下 osquery 来执行此操作:

  SELECT DISTINCT pid, name, proc.path FROM process_memory_map AS pmm JOIN processes AS proc USING(pid) WHERE pmm.path LIKE '%uiautomationcore.dll'

加载 UIAutomationCore.dll 的进程

  WITH uia_pipes AS (SELECT name AS pipe_name, SUBSTR(name, 10, INSTR(SUBSTR(name, 10), '_')-1) AS pid FROM pipes WHERE name LIKE 'UIA_PIPE_%' ) SELECT DISTINCT pid, name AS process_name, path, pipe_name FROM uia_pipes JOIN processes USING(pid)

打开 UI Automation 命名管道的进程

结论

这项分析揭示了一个令人遗憾的案例,即原本出于善意而开发的技术如何遭劫持并用于恶意目的。尽管 UI Automation 框架对残障人士有所帮助,但它也让攻击者有机会模仿间谍软件。

虽然利用 UIA 入侵可能比其他一些攻击更困难,但由于它能躲避 EDR 检测,因而可能会让 UIA 成为一个极具吸引力的攻击面。为了削弱 UIA 对攻击者的吸引力,Microsoft 对其设置了一系列限制,但如果攻击者拥有足够的技术能力,仍然可以利用 UIA。我们希望这篇博文能让人们深入了解这类攻击手段,并帮助蓝队抵御这种攻击媒介。



Tomer Peled

寫於

Tomer Peled

December 11, 2024

Tomer Peled

寫於

Tomer Peled

Tomer Peled 是 Akamai 的安全研究员。他的日常研究工作主要涉及漏洞和操作系统内部结构等方面。闲暇时,他喜欢烹饪美食、练马伽术以及玩 PC 游戏。