恶意软件通常需要计算机上的完全管理权限来执行更有影响的操作,如添加逃避防病毒软件检测、加密安全文件或向感兴趣的系统进程中注入代码。即使目标用户拥有管理权限,用户帐户控制(UAC)的流行也意味着恶意应用程序通常默认为中等完整性,从而阻止对具有较高完整性级别的资源的写入访问。要绕过这个限制,攻击者将需要一种无需用户交互(无 UAC 提示)静默提升完整性级别的方法。这种技术被称为绕过用户帐户控制,它依赖于各种原语和条件,其中大部分基于搭载提升的 Windows 功能。
以 Medium 身份运行的 cscript.exe 示例通过 UAC 绕过生成具有高完整性的 cmd.exe 实例:
大多数 UAC 验证逻辑是在应用程序信息 (AppInfo) 服务中实现的。我们将在本文介绍一组 UAC 绕过,调查它们所依赖的一些关键原语以及对应的检测方式。
UAC 绕过方法
UAC 绕过方法通常会通过生成恶意子进程或加载继承目标应用程序提升的完整性级别的恶意模块来劫持提升的应用程序的正常执行流程。
还有一些其他极端情况,但最常见的劫持方法是:
注册表键操作
操作注册表键的目的是将提升程序的执行流程重定向到受控命令。最常被滥用的键值与特定扩展的 shell 打开命令(取决于目标程序)或 windir/systemroot 环境变量操作有关:
HKCU\\Software\\Classes\\\shell\\open\command (默认或DelegateExecute值); HKCU\\Environment\\windir; HKCU\\Environment\\systemroot;
例如,当fodhelper(一个Windows二进制文件,允许提升而不需要UAC提示)被恶意软件作为Medium完整性进程启动时,Windows会自动将fodhelper从Medium完整性进程提升到High完整性进程。然后,高完整性fodhelper尝试使用其默认的处理程序打开ms-settings文件。由于中等完整性的恶意软件已经劫持了这个处理程序,被提升的fodhelper将执行攻击者选择的一个命令作为一个高完整性进程。
下面是一个 Glupteba 恶意软件的示例,它利用这种方法首先从中等完整性进程提升到高完整性过程,然后通过令牌操纵(令牌窃取)从高完整性进程提升到系统完整性:
操纵 Windows 环境变量注册表键的 UAC 绕过示例是 byeintegrity5。为了说明这一点,此绕过使用此原语重定向 CDSSync 计划任务的正常执行流程(设置为以最高权限运行),并提升完整性级别,如下所示。
当 CDSSync 计划任务运行时,taskhostw.exe 会尝试从 %windir%\System32 文件夹加载 npmproxy.dll,但因为恶意软件控制了%windir%,它可以重定向taskhostw.exe从它控制的路径加载一个名为npmproxy.dll的DLL,如下所示。
当 UAC 设置为 Always Notify(最高 UAC 级别)时,基于环境变量操作的 UAC 绕过通常会起作用,因为它们通常不涉及将文件写入安全路径或启动自动提升应用程序。从当前用户注册表更改 SystemRoot 或 Windir 到非预期值是非常可疑的,应该是检测的高置信度信号。
DLL 劫持
DLL劫持方法通常包括找到一个丢失的DLL(通常是一个丢失的依赖项),或者通过将一个恶意的DLL加载到一个提升进程中来赢得DLL文件写入进程。如果 UAC 已启用但未设置为 Always Notify,则恶意软件可以执行提升的 IFileOperation(无 UAC 提示)来创建/复制/重命名或将 DLL 文件移动到受信任的路径(即 System32),然后触发提升的程序加载恶意 DLL 而不是预期的。
IFileOperation 由 dllhost.exe(COM 代理)执行,其中 process.command_line 包含 classId {3AD05575-8857-4850-9277-11B85BDB8E09}。
我们可以使用以下 EQL 关联来链接 dllhost.exe 的任何文件操作,然后将一个非microsoft签名的DLL加载到一个运行系统完整性的进程中:
这是一个检测UACME 30将wow64log.dll侧载到作为系统运行的WerFault.exe实例的示例(它提供了一个很好的从Medium到System完整性的直接跳转),如下所示。
如果 UAC 设置为 Always Notify,则查找丢失的 DLL 或赢得文件写入竞争条件到可由中等完整性进程写入的路径是一个有效选项。这是 UAC 绕过劫持 SilentCleanup 计划任务(通过文件写入竞争条件)的示例,该任务会产生从 AppData 子文件夹(可由中等完整性写入)执行的高完整性后代进程 DismHost.exe,这是另一个滥用相同的变体任务,但缺少依赖项api-ms-win-core-kernel32-legacy-l1.dll。
另一个可以实现相同目标的 DLL 劫持原语是使用 DLL 加载重定向,方法是在目标提升程序的同一目录中创建一个文件夹(例如 target_program.exe.local 并在其中放置一个将被加载而不是预期的 DLL )。
此技术也可用作本地权限提升的原语,以防漏洞允许创建文件夹(具有许可的访问控制列表)到受控位置,例如 Jonas Lykkegård 在本文中描述的从directory deletion到SYSTEM shell的内容。
此查询与 UACME 方法 22 匹配,该方法针对consent.exe(作为系统执行),欺骗它从SxS DotLocal目录加载comctl32.dll,而不是System32:
值得一提的是,大多数通过 DLL 劫持绕过 UAC 对持久性也很有用,并且可能会绕过基于自动运行(已知文件和注册表持久性位置)的检测。
提升的 COM 接口
此方法与前面的方法稍有不同,这意味着不涉及直接操作重定向。相反,它依赖于找到一个提升的 COM 接口,该接口公开了某种形式的执行能力(即 CreateProcess / ShellExec 包装器),可以调用它来启动一个通过中等完整性进程的参数传递的特权程序。
从操作的角度来看,通常这些 COM 接口将在 dllhost.exe(COM 代理)的上下文中执行,其中 process.command_line 包含目标 COM 对象的 classId,这通常会导致创建高完整性子进程。
以下是不同的恶意软件家族采用这种方法进行UAC绕过的例子(如DarkSide和LockBit勒索软件家族),在启动加密和逃避能力之前提高完整性水平,很难预防:
令牌安全属性
James Forshaw 对利用进程令牌安全属性来识别作为自动提升应用程序的后代启动的进程的可能性进行了深入的观察。
ProcessHacker 也捕获此类信息。下面是通过 fodhelper UAC 绕过启动的 notepad.exe 实例的令牌属性示例。
LUA://HdAutoAp属性意味着它是一个自动提升的应用程序(也为提升的COM对象和AppInfo硬编码的白名单进程填充)。DecHdAutoAp意味着它是一个自动提升应用程序的后代,这在跟踪通过UAC绕过生成的进程树时非常有用。
Elastic Endpoint 安全 7.16 及更高版本通过流程执行事件 (process.Ext.token.security_attributes) 捕获此信息,这为在没有先验知识的情况下寻找和检测 UAC 绕过劫持自动提升程序或 COM 接口的执行流提供了机会绕过细节(目标二进制、COM 接口、重定向方法和其他重要细节):
可疑的自动提升程序子进程:
上面的查询还匹配UAC旁路的所有后代进程,而不仅仅是直接子进程。
我们可以看到这种方法通过注册表键操作检测 fodhelper 执行流劫持:
这是通过模拟受信任目录的匹配 UAC 绕过的示例:
以下是通过 Elevated COM 接口匹配 3 种不同 UAC 旁路的示例:
逃避检测
有研究人员发表了一篇文章,讨论了许多不限于绕过 UAC 的逃避技术,例如重命名文件夹或注册表键、注册表符号链接以基于特定文件路径/注册表键更改或不同的关联来破坏检测逻辑同一过程的事件。不过大多数恶意软件家族都不会费心修改和调整这些技术。
下面是一个通过目录重命名(UACME 22)逃避文件监控的示例。
下面是一个通过键重命名(byyeintegrity8)来监控注册表键路径逃避的示例。
最近添加到 UACME v.3.5.7 的另一个有趣的逃避技巧是 CurVer 子键,可用于重定向 shell 默认处理程序。这有效地绕过了寻找硬编码可疑注册表路径/值的检测:
对于与DLL劫持相关的基于文件的检测,最好使用DLL加载事件(Elastic Endpoint Security 7.16日志非microsoft签名的DLL)。对于注册表来说,需要混合注册表。字符串和值名应该比完整的键路径更有弹性。
下面的EQL相关示例展示了如何检测伪装成 System32 的目录中的 DLL 加载(即作为 windir/systemroot 环境变量修改的结果):
此示例显示了两种不同的匹配技术(注册表键操作和通过虚假Windir劫持DLL):
下一个示例结合了注册表符号链接和注册表键重命名,以逃避基于注册表键更改监视(ms-settings 或 shell\open\command)的 fodhelper UAC 绕过检测:
UACME v.3.5及以上版本实现了对涉及注册表键操作的方法的这种逃避。
你可以使用Elastic Endpoint或Sysmon日志查找注册表符号链接的创建,方法是查找值名称等于SymbolicLinkValue的注册表修改。
用于检测此逃避的示例 KQL 查询是:registry.value :"SymbolicLinkValue" 和 registry.key :S-1-5-21-15Classes\\*`:
最常见的 UAC 绕过
在野外使用的恶意软件家族回不断变化和迭代。以下是恶意软件家族常用的UAC绕过方法:
通过 UAC 绕过最常见的执行命令是恶意软件以高完整性重新执行自身或防御逃避技术,例如:
篡改 AV 防御策略;
写入受 HKLM 保护的注册表键;
篡改系统恢复设置;
总结
在这篇文章中,我们介绍了UAC绕过的主要方法,以及如何检测它们,以及如何用令牌安全属性丰富流程执行事件,使我们能够创建一个更广泛的检测逻辑,以匹配未知的绕过。
本文翻译自:https://elastic.github.io/security-research/whitepapers/2022/02/03.exploring-windows-uac-bypass-techniques-detection-strategies/article/如若转载,请注明原文地址