1. 项目概述:从“提权”到“绕过”的攻防博弈
在红队评估或渗透测试的后期阶段,我们常常会遇到一个尴尬的局面:通过初始漏洞(比如一个钓鱼邮件载荷或者一个WebShell)成功在目标Windows系统上获得了立足点,拿到了一个普通用户权限的会话。然而,当我们试图执行一些关键操作,比如安装后门、转储凭据、修改系统配置时,系统会弹出一个熟悉的蓝色盾牌窗口——用户账户控制(UAC)。这个自Windows Vista时代引入的安全机制,就像一道横亘在普通用户权限和完整管理员权限之间的“安检门”。对于攻击者而言,无法绕过UAC,就意味着攻击链在此中断,无法实现真正的权限提升(Privilege Escalation)。因此,掌握一套行之有效的UAC绕过技术,是渗透测试人员从“立足”走向“扎根”的必修课。
Cobalt Strike作为一款成熟的商业渗透测试框架,其强大的后渗透(Post-Exploitation)能力备受推崇。它不仅仅是一个C2(命令与控制)服务器,更是一个集成了大量自动化攻击模块的“武器库”。在提权方面,Cobalt Strike内置了多种UAC绕过技术,允许攻击者在获得初始立足点后,以更高的完整性级别(通常是High或System)执行后续载荷。然而,这些技术并非“银弹”,其成功率高度依赖于目标系统的环境、配置、补丁级别以及杀毒软件的状态。盲目使用默认模块,很可能触发告警或直接失败。本文旨在结合我多年的实战经验,深入剖析Cobalt Strike中五种经典的UAC绕过技术原理,并提供详细的实战操作步骤、环境适配要点以及至关重要的“避坑指南”。我们将从最基础的原理讲起,逐步深入到复杂的Bypass技巧,确保你不仅能“知其然”,更能“知其所以然”,在面对不同目标时能够灵活选择、组合甚至创新绕过方法。
2. UAC机制核心原理与绕过思路拆解
在深入具体技术之前,我们必须先理解我们试图绕过的“对手”。用户账户控制(UAC)的核心设计目标,是在用户(即使是管理员)执行可能影响系统全局的操作时,强制进行一次显式的、知情同意式的授权。它通过完整性级别(Integrity Levels)和权限令牌(Token)来实现这一目标。
2.1 完整性级别与权限令牌
Windows系统为进程和对象(如文件、注册表键)分配了不同的完整性级别,从低到高分别为:Untrusted, Low, Medium, High, System。默认情况下,以普通用户身份启动的进程拥有Medium完整性级别。当进程尝试执行需要更高权限的操作(如写入C:\Windows\System32)时,系统会检查其令牌。
管理员用户的令牌实际上有两份:一份是“过滤后的”标准用户令牌(具有Medium完整性级别),用于日常操作;另一份是“完整的”管理员令牌,处于休眠状态。当UAC对话框弹出并用户点击“是”后,系统会使用完整的令牌创建一个新的进程(通常是consent.exe的子进程),这个新进程就拥有了High完整性级别。
2.2 自动提升与受信任的发布者
UAC并非对所有操作都“一刀切”地弹窗。它定义了一系列“自动提升”规则。如果一个可执行文件满足以下条件之一,系统可能会在不弹窗的情况下,直接以高完整性级别启动它:
- 位于受信任的系统目录:如
%SystemRoot%\System32\、%ProgramFiles%\。 - 具有来自受信任发布者的数字签名:并且其清单(manifest)中明确请求了
requireAdministrator执行级别。 - 由Windows自身或已提升的进程启动。
我们的绕过技术,本质上就是“欺骗”系统,让我们的恶意进程满足上述的自动提升条件,或者利用系统在提升逻辑中的漏洞,在不触发UAC弹窗的情况下,获取高完整性令牌。
2.3 Cobalt Strike的绕过思路分类
基于上述原理,Cobalt Strike内置的绕过技术大致可以分为三类思路:
- DLL劫持/搜索顺序劫持:利用系统进程(如
fodhelper.exe,eventvwr.exe)在加载DLL时的缺陷,将恶意DLL放置在比合法DLL更优先被搜索的位置,从而在目标进程启动时加载我们的代码。由于父进程是系统信任的,其子进程可能获得自动提升。 - COM接口滥用:利用某些COM对象(Component Object Model)在实例化时,其宿主进程(如
mmc.exe,dllhost.exe)默认以高完整性级别运行的特点。通过修改注册表,将COM对象的处理程序指向我们的恶意可执行文件。 - Windows文件操作漏洞:利用系统在处理特定文件路径、符号链接或对象管理器命名空间时的逻辑缺陷,诱使一个高权限进程执行或加载我们控制的代码。例如,经典的
IFileOperation漏洞(CVE-2019-1388)就属于此类。
理解这些底层思路,比死记硬背几个模块命令重要得多。它让你能在工具失效时,自己分析原因,甚至寻找新的绕过路径。
3. 五种经典UAC绕过技术实战解析
下面,我们将结合Cobalt Strike的elevate命令,逐一拆解五种常见的UAC绕过模块。假设我们已经通过一个windows/beacon_http/reverse_http的监听器,获得了一个普通用户权限的Beacon会话(会话ID为1)。
3.1 技术一:uac-eventvwr模块
这是最古老、最经典的绕过方法之一,利用了eventvwr.exe(事件查看器)的DLL搜索顺序漏洞。
原理:eventvwr.exe在启动时,会尝试加载%SystemRoot%\system32\下的mmc.exe来显示管理界面。但它首先会检查注册表键HKCU\Software\Classes\mscfile\shell\open\command的默认值。如果该值存在,它会将其作为命令行来启动。关键点在于,检查这个注册表键的操作发生在提升权限之前。因此,我们可以先以当前用户权限写入该注册表键,指向我们的恶意可执行文件,然后启动eventvwr.exe。系统会读取我们设置的注册表键,并以此命令行启动一个进程,而这个进程因为是由受信任的eventvwr.exe(通过COM机制)触发的,从而继承了高完整性级别。
Cobalt Strike操作:
beacon> elevate uac-eventvwr [listener]例如:elevate uac-eventvwr http
实战步骤与细节:
- 前置检查:在执行前,务必检查目标系统是否安装了
.NET Framework的某个版本。因为Cobalt Strike生成的绕过载荷通常是一个.NET可执行文件。可以通过beacon> shell powershell “Get-ItemProperty -Path ‘HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP’ -Name Version”粗略判断。 - 模块执行:执行上述
elevate命令后,Cobalt Strike会做以下几件事:- 在Beacon会话中,写入上述提到的注册表键,值设置为一个临时路径下的攻击载荷(一个.exe文件)。
- 通过
ShellExecute或类似API启动eventvwr.exe。 eventvwr.exe读取被篡改的注册表键,执行我们的攻击载荷。- 攻击载荷在内存中反射加载Beacon的Stage,并与我们的Listener建立连接,从而获得一个高权限的Beacon会话。
- 清理痕迹:新的高权限Beacon建立后,原始的注册表键会被模块自动清理。但有时清理可能失败,需要手动检查:
beacon> reg query HKCU\Software\Classes\mscfile\shell\open\command。
避坑指南:
- 补丁影响:此方法在较新的Windows 10/11系统上,如果所有安全更新都已安装,成功率已经大大降低。微软通过修改
eventvwr.exe的启动逻辑修复了此漏洞。因此,它主要适用于未及时更新的内网环境。 - 杀软查杀:写入注册表
Run键或特定Classes键是很多EDR/杀软监控的重点行为。生成的.exe文件如果落地,也极易被静态查杀。建议配合Cobalt Strike的Artifact Kit生成免杀载荷,或使用execute-assembly等无文件技术来运行后续操作。 - 路径问题:如果当前用户的
TEMP目录路径包含空格或特殊字符,可能会导致生成的命令行解析错误,从而使绕过失败。这是一个隐蔽的坑点。
3.2 技术二:uac-fodhelper模块
这是另一个基于DLL搜索顺序劫持(或更准确说是协议处理程序劫持)的方法,利用了fodhelper.exe(Windows功能助手)程序。
原理:fodhelper.exe是一个用于管理Windows可选功能的组件,默认以高完整性级别运行。当通过特定URL协议(如ms-settings:)调用它时,它会查找该协议关联的应用程序。我们可以劫持一个不常用或可写的URL协议处理程序(例如ms-settings\下的某个子项),将其指向我们的恶意可执行文件。当fodhelper.exe被触发时,它会启动我们指定的程序,并继承高权限。
Cobalt Strike操作:
beacon> elevate uac-fodhelper [listener]实战步骤与细节:
- 模块流程:该模块通常会劫持
HKCU\Software\Classes\ms-settings\shell\open\command下的注册表项。将(Default)值和DelegateExecute值清空或修改,使得fodhelper.exe在处理ms-settings协议时,直接执行我们设定的命令行。 - 触发方式:模块通过
ShellExecute或直接创建进程的方式启动fodhelper.exe。由于fodhelper.exe本身是受信任的、会自动提升的程序,它启动的子进程(我们的载荷)也就获得了高权限。
避坑指南:
- 注册表权限:现代Windows系统对
HKCU\Software\Classes\ms-settings\及其子键的权限控制可能更严格。在某些配置下,普通用户可能无法成功写入DelegateExecute值。如果遇到权限错误,需要尝试其他方法。 - 行为检测:修改
ms-settings相关的注册表键,是一个偏离正常用户行为非常明显的动作,容易被高级EDR(端点检测与响应)产品标记。在对抗性强的环境中需谨慎使用。 - 清理时机:和
eventvwr方法一样,清理注册表键的时机至关重要。如果在新Beacon建立前清理,可能导致执行失败;如果清理失败,则会留下明显的攻击痕迹。最好在获得高权限会话后,手动检查并清理。
3.3 技术三:uac-silentcleanup模块
这个方法利用了Windows计划任务中的一个特性,更具隐蔽性。
原理:Windows系统中存在一个名为SilentCleanup的计划任务,其触发事件是用户日志off。这个任务默认以NT AUTHORITY\SYSTEM权限运行,但关键特性是:它可以在用户登录后,以用户上下文(并且是高完整性级别)运行。更妙的是,该任务在启动时会检查环境变量%windir%\System32\,但如果该路径不存在(这不可能),它会回退到使用%windir%\Sysnative\?不,这里有一个精妙的利用点:该任务的操作(Action)中指定的可执行文件路径是%windir%\system32\cleanmgr.exe,但我们可以通过DLL劫持或路径劫持来干扰它。实际上,更常见的利用方式是劫持该任务运行时依赖的一个DLL,或者利用其工作目录等特性。Cobalt Strike的模块实现可能更直接地利用了任务本身可以运行脚本或可执行文件的特性,通过修改注册表或文件关联来实现。
Cobalt Strike操作:
beacon> elevate uac-silentcleanup [listener]实战步骤与细节:
- 环境准备:此方法通常需要目标系统启用计划任务服务,并且
SilentCleanup任务处于就绪状态。可以通过beacon> shell schtasks /query /tn \Microsoft\Windows\DiskCleanup\SilentCleanup /fo list /v来查看任务详情。 - 利用本质:模块并非直接触发任务,而是利用任务配置中的某个环节。一种已知的利用方式是,该任务在运行时会调用
cleanmgr.exe,而cleanmgr.exe会加载一系列DLL。通过将恶意DLL放置在cleanmgr.exe的搜索路径中(例如当前目录,而任务的工作目录可能是可写的用户目录),可以实现DLL劫持。Cobalt Strike的模块可能自动化了放置恶意DLL和触发任务(或触发任务运行条件)的过程。
避坑指南:
- 系统版本差异:
SilentCleanup任务的具体行为和配置在不同版本的Windows(如Win10 1607, 1809, Win11)中可能有细微差别,可能导致利用失败。 - 杀软监控:计划任务的创建、修改以及
cleanmgr.exe进程的异常DLL加载行为,都是安全软件监控的重点。此方法的动静可能比前两种更大。 - 可靠性:由于依赖系统组件的特定实现细节,此方法的稳定性不如前两种广泛流传的方法,在某些系统上可能无法工作。它更适合作为备用方案。
3.4 技术四:uac-wscript模块
这是一个利用Windows脚本宿主(wscript.exe或cscript.exe)和COM组件交互的绕过方法。
原理:某些COM组件在实例化时,其宿主进程(如wscript.exe)会尝试以高完整性级别运行。通过编写一个JScript或VBScript脚本,该脚本创建特定的COM对象(例如ShellWindows或ShellBrowserWindow),可以导致脚本宿主进程提升权限。然后,在这个高权限的脚本上下文中,我们可以执行命令来启动我们的后门。Cobalt Strike的模块将生成一个恶意脚本文件,并利用此机制执行。
Cobalt Strike操作:
beacon> elevate uac-wscript [listener] [可选:脚本语言,如 jscript]实战步骤与细节:
- 脚本生成与投放:执行命令后,Cobalt Strike会在当前用户的临时目录或指定位置生成一个
.js或.vbs脚本文件。这个脚本包含了利用COM提升权限并执行Payload的代码。 - 执行过程:模块会启动
wscript.exe(图形界面)或cscript.exe(命令行界面)来运行这个脚本。在脚本执行过程中,通过COM操作触发UAC自动提升逻辑,使得wscript.exe进程获得高完整性级别,进而执行嵌入的Payload。
避坑指南:
- 脚本文件落地:这是该方法最大的弱点。在磁盘上生成一个脚本文件(.js/.vbs),几乎100%会被现代端点安全软件实时扫描并查杀。即使脚本内容经过混淆,其启动
wscript.exe并执行特定COM操作的行为链也容易被检测。 - AMSI绕过:如果脚本内容被Antimalware Scan Interface (AMSI) 捕获,简单的字符串特征就可能导致拦截。需要在脚本中集成AMSI绕过技术,这增加了复杂度。
- 适用场景:因此,
uac-wscript模块在高度对抗的环境下并不理想。它可能适用于某些EDR覆盖较弱、或对脚本行为监控不严的内部环境。
3.5 技术五:uac-token-duplication模块
这是一种相对高级的技术,它不依赖于特定的系统程序漏洞,而是利用Windows令牌模拟(Token Impersonation)和进程注入技术。
原理:在Windows中,即使一个进程以中等完整性级别运行,如果它能打开一个高完整性级别进程的句柄(并具有足够的权限,如PROCESS_QUERY_INFORMATION),它就可以复制(Duplicate)那个进程的令牌。系统中总有一些以高权限运行的系统进程或服务进程。该技术的核心是:
- 在当前中等权限的进程中,枚举进程列表,寻找一个以高完整性级别运行、并且当前用户能够打开进程句柄的目标进程(例如,
explorer.exe在管理员登录后通常以High权限运行)。 - 打开该目标进程的句柄,复制其访问令牌。
- 使用复制的令牌创建一个新的进程(我们的Beacon),这个新进程就继承了高完整性级别。
Cobalt Strike操作: Cobalt Strike可能通过execute-assembly或powerpick调用实现了此技术的.NET或PowerShell脚本。命令可能类似:
beacon> powershell-import /path/to/Invoke-TokenDuplication.ps1 beacon> powershell Invoke-TokenDuplication -Listener http或者有内置的模块命令。
实战步骤与细节:
- 寻找目标进程:脚本会遍历进程,通常寻找
explorer.exe,因为它是用户会话中的高权限进程,且普通用户通常对其拥有PROCESS_QUERY_INFORMATION权限。其他候选可能包括dwm.exe,taskhostw.exe等。 - 令牌复制与进程创建:使用
OpenProcess->OpenProcessToken->DuplicateTokenEx这一系列Win32 API调用来复制令牌。然后使用CreateProcessWithTokenW或CreateProcessAsUser函数,以复制的令牌创建新进程。 - 无文件化:整个过程可以在内存中完成,无需在磁盘上落地任何可执行文件。Payload可以通过反射DLL注入或进程镂空(Process Hollowing)等技术直接注入到新创建的进程中。
避坑指南:
- 权限要求:成功的关键在于能否打开高权限进程的句柄。如果目标系统启用了严格的进程隔离策略(如某些加固的Windows 10/11配置),或者有安全软件对
OpenProcess调用进行监控和拦截,此方法会失败。 - 进程选择:并非所有高权限进程都可用。
svchost.exe等服务进程通常属于不同的会话或具有不同的权限属性,无法直接用于创建用户会话下的进程。选择explorer.exe是最常见的,但如果用户没有运行桌面(例如在服务器上通过RDP连接但没有交互式登录),此方法可能失效。 - 检测点:令牌复制和跨进程创建是EDR深度监控的敏感操作。
CreateProcessWithTokenW这样的函数调用是明显的提权行为特征。需要配合API钩子绕过或直接系统调用(Syscall)来降低检测概率。
4. 实战环境选择与组合利用策略
了解了五种技术后,你可能会问:我该用哪一个?答案是:视情况而定,并做好组合尝试的准备。没有一种方法能通吃所有环境。
4.1 环境侦察与方法选型
在尝试绕过之前,花几分钟进行侦察可以大幅提高成功率,避免无谓的告警。
检查系统信息:
beacon> shell systeminfo | findstr /B /C:“OS Name” /C:“OS Version” beacon> shell ver确定Windows版本和大致内部版本号,可以推断系统可能打了哪些补丁。
检查UAC设置:
beacon> reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin beacon> reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUAConsentPromptBehaviorAdmin值为0表示“不提示,直接提升”(最弱),5表示“在安全桌面上提示”(默认),2或3也会提示但行为略有不同。EnableLUA值为1表示UAC启用(默认),为0则表示UAC被完全禁用(此时无需绕过,直接就是高权限)。注意:在渗透测试中,除非有明确授权,否则不应修改此值,因为这会降低系统安全性。
检查杀软/EDR:通过
ps或tasklist查看运行的安全进程。也可以尝试运行一些无害的命令观察反应。
选型建议:
- 老旧/未更新系统:优先尝试
uac-eventvwr或uac-fodhelper,它们简单直接。 - 更新至最新版本的系统:
eventvwr和fodhelper可能失效,应尝试uac-token-duplication或uac-silentcleanup。 - 对抗性强的环境(有EDR):优先考虑无文件、行为隐蔽的方法。
uac-token-duplication(如果实现得好)和经过高度混淆的uac-wscript(结合AMSI绕过)可能有机会。绝对要避免直接落地可执行文件(.exe)。 - 打“组合拳”:如果第一种方法失败,不要立即重试同一种方法。先清理痕迹(如注册表键),然后尝试原理不同的另一种方法。例如,
eventvwr失败后,可以尝试token-duplication。
4.2 Cobalt Strike中的自动化与手动利用
Cobalt Strike的elevate模块提供了自动化,但知其然也要知其所以然。手动利用可以更灵活、更隐蔽。
手动利用示例(以eventvwr为例): 假设我们已经有一个PowerShell或C#的二进制Payload(payload.exe)。
- 上传Payload:将
payload.exe上传到目标可写目录,如C:\Users\Public\。 - 修改注册表:
(注意:实际路径可能需要处理空格和引号,Cobalt Strike的模块会处理这些细节)beacon> reg setval -k “HKCU\Software\Classes\mscfile\shell\open\command” -v “” -d “C:\Users\Public\payload.exe” - 触发eventvwr:
或者使用beacon> shell start eventvwr.mscShellExecuteAPI。 - 清理注册表:
beacon> reg delete -k “HKCU\Software\Classes\mscfile\shell\open\command”
手动利用的好处是可以控制每一步的时机和方式,可以插入延迟、使用不同的触发方法,有时能绕过一些简单的自动化检测。
5. 高级规避技术与深度避坑指南
在实战中,仅仅成功执行绕过获取高权限会话是不够的。我们还需要考虑如何规避安全产品的检测,以及如何处理各种意外情况。
5.1 对抗杀软与EDR的要点
- 载荷免杀是基础:Cobalt Strike默认生成的Payload(无论是
exe、dll还是ps1)特征都非常明显。务必使用Artifact Kit或自定义的模板对生成的PE文件进行混淆、加壳或修改特征。对于PowerShell脚本,要使用混淆工具(如Invoke-Obfuscation)并内嵌AMSI绕过代码。 - 减少磁盘操作:优先使用内存执行技术。在Cobalt Strike中,这意味着:
- 使用
execute-assembly在内存中加载.NET程序集执行UAC绕过逻辑。 - 使用
powerpick或psinject来运行PowerShell脚本,避免powershell.exe进程拉取磁盘上的脚本文件。 - 如果必须落地文件,选择偏僻的、非常规的目录(如
C:\Windows\Tasks\,C:\Windows\Temp\下的随机子目录),并在执行后立即删除。
- 使用
- API调用监控绕过:高级EDR会钩住(Hook)关键的Win32 API,如
CreateProcess,WriteProcessMemory,DuplicateTokenEx等。可以考虑:- 使用直接系统调用(Syscall)来替代这些API。这需要自己编写或使用实现了Syscall的Shellcode/Loader。
- 使用合法的Windows工具进行“Living-off-the-Land”(LOLBAS),例如使用
cmstp.exe、msiexec.exe等自带数字签名的程序来间接执行代码,但这通常用于执行阶段而非直接的UAC绕过。
- 行为链伪装:分析每种UAC绕过技术产生的进程链。例如,
eventvwr -> 你的payload。EDR可能会检测这种异常的父子进程关系。可以尝试通过进程镂空、父进程PID欺骗等技术来伪装进程链,使其看起来更正常。
5.2 常见失败场景排查表
| 现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
执行elevate后无新会话 | 1. Payload被终端安全软件拦截。 2. 绕过技术本身失效(已打补丁)。 3. Listener配置错误或网络不通。 4. 注册表写入失败或触发失败。 | 1. 检查杀软日志(如果可能),尝试对Payload进行免杀处理。 2. 换一种绕过技术尝试。 3. 在Beacon中使用 checkin命令测试原会话是否存活,并确认Listener配置正确。4. 手动执行注册表操作和触发命令,看是否有错误信息。 |
| 弹出UAC对话框 | 绕过技术未能实现“静默”提升,触发了UAC弹窗。 | 1. 确认目标UAC级别不是最高(“始终通知”)。 2. 该绕过技术可能不适用于当前系统版本。换用其他方法。 3. 检查当前用户是否在管理员组内。非管理员用户无法提升。 |
| 新会话产生后立即死亡 | 1. Payload不稳定或存在兼容性问题。 2. 被EDR的动态行为检测击杀。 3. 令牌复制后创建的进程属性异常。 | 1. 尝试使用更稳定的Payload类型(如windows/beacon_http/reverse_http比windows/beacon_bind_pipe更通用)。2. 尝试在非工作时间或使用更隐蔽的进程注入技术。 3. 对于令牌复制,确保创建进程时指定了正确的会话ID和桌面。 |
| 注册表键清理失败 | 模块的清理逻辑有bug,或清理时机不对(在新进程完全启动前就清理了)。 | 手动清理残留的注册表键。这是一个重要的痕迹清理步骤,务必完成。 |
5.3 权限维持与后续操作
成功绕过UAC获得高权限Beacon后,你拥有了一个宝贵的“跳板”。此时,不应满足于此,而应迅速开展后续工作,并建立更稳固的权限维持机制。
- 转储凭据:立即使用
mimikatz或Cobalt Strike内置的logonpasswords命令转储LSASS内存中的密码哈希和明文(如果系统支持)。这是内网横向移动的“燃料”。 - 权限维持:在高权限下,可以部署更隐蔽的后门。
- 计划任务:创建以SYSTEM或高权限用户运行的计划任务。
- 服务:安装一个新的Windows服务。
- WMI事件订阅:这是一种非常隐蔽的持久化方式。
- 注册表启动项:修改
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run等位置。注意:在部署持久化时,要确保其启动的Payload也是免杀的,并且行为尽可能低调。
- 关闭防御(需谨慎,并符合测试规则):在高权限下,可能可以临时禁用防病毒软件、修改Windows Defender设置或添加排除项。但这会产生大量告警日志,仅在必要时使用。
- 横向移动准备:收集网络信息(
net view,ipconfig /all)、共享信息、域信息等,为下一步攻击做准备。
绕过UAC不是终点,而是一个关键的转折点。它标志着攻击从外部突破转向了内部扎根。掌握多种技术,理解其原理,并具备根据环境灵活选择和排错的能力,是一名专业渗透测试人员红队评估中不可或缺的技能。每一次成功的绕过,都是对系统防御体系一次深刻的洞察。