ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

逐行读懂 BlueHammer 的 wmain:Windows 本地提权 PoC 代码阅读指南(附流程图)

逐行读懂 BlueHammer 的 wmain:Windows 本地提权 PoC 代码阅读指南(附流程图) 逐行读懂 BlueHammer 的 wmainWindows 本地提权 PoC 代码阅读指南附流程图【免费下载链接】BlueHammerRepository hosting the bluehammer vulnerability项目地址: https://gitcode.com/gh_mirrors/bl/BlueHammerBlueHammer 是一个 Windows 本地提权漏洞的 PoCProof of Concept开源程序它利用 Windows Defender 引擎签名更新路径中的缺陷实现从普通用户到 SYSTEM 权限的完整提权链路其全部核心逻辑集中在 FunnyApp.cpp 的wmain入口函数中。本文带你逐段读懂这个 wmain并附上一张完整执行流程图帮你建立阅读 Windows 提权 PoC 代码的方法。⚠️合规提醒本文为安全研究与防御视角的代码阅读材料。请勿在真实生产环境中运行该 PoC严禁用于任何非法用途。一、先认识项目BlueHammer 仓库结构速览在逐行读代码之前先用一张表建立全局地图。整个仓库很小每个文件各司其职文件作用FunnyApp.cppPoC 主程序包含wmain入口与全部漏洞利用逻辑windefend.idlWindows Defender RPC 接口的 MIDL 定义文件windefend_h.h由 MIDL 生成的 RPC 客户端头文件含全部 Proc 函数原型windefend_c.c自动生成的 RPC 客户端存根stuboffreg.h离线注册表库头文件用于直接打开离线的 SAM 文件offreg.lib离线注册表库对应 offreg.h 的实现FunnyApp.rc / resource.h资源脚本与资源定义FunnyApp.sln / FunnyApp.vcxprojMSVC 解决方案与工程文件README.md项目说明提权链路一句话版等待 Defender 引擎签名更新 → 触发卷影副本VSS快照 → 冻结 Defender 进程 → 用对象符号链接把受保护的mpasbase.vdm路径重定向到快照里的 SAM 文件 → 事务方式打开并读取 SAM → 解密 NTLM 哈希并临时改密码 → 以 SYSTEM 身份拉出 shell。二、wmain 执行流程图在逐行解析前先看 wmain 的完整控制流记住这张图下面每一小节都会对应图中的某个节点。三、逐段解析 wmain对应流程图节点3.1 入口分支SYSTEM 二次启动模式 程序的第一行逻辑就在判断自己是不是二次启动if (IsRunningAsLocalSystem()) { if (argc 2) { DWORD sessionid _wtoi(argv[1]); LaunchConsoleInSessionId(sessionid); } return 0; }见 FunnyApp.cpp#L2868-L2880。IsRunningAsLocalSystem 通过查询进程令牌中的WinLocalSystemSid判断当前身份。当提权成功后以 SYSTEM 身份重新拉起本程序时走这条分支LaunchConsoleInSessionId 启用SE_TCB、SE_ASSIGNPRIMARYTOKEN等特权复制令牌、改写TokenSessionId再CreateProcessAsUser拉起一个conhost.exe控制台——这是普通用户能看见的最终成果。3.2 等待时机轮询 Defender 签名更新 const wchar_t* filestoleak[] { {L\\Windows\\System32\\Config\\SAM} }; ... while (!CheckForWDUpdates(updtitle, criterr)) { printf(No updates found ... Recheking in 30 seconds...\n); Sleep(30000); }见 FunnyApp.cpp#L2884-L2880 与 FunnyApp.cpp#L2971-L2980。CheckForWDUpdates 调用 Windows Update 的 COM 接口Microsoft.Update.Session每 30 秒搜一次直到找到Microsoft Defender Antivirus Definition Updates类别的更新。为什么必须等更新因为整个攻击要借Defender 的引擎签名更新流程让 Defender 自己以 SYSTEM 身份去打开攻击者控制路径的文件。3.3 预备更新包下载并内存解包 找到更新后GetUpdateFiles 做三件事从官方更新链接下载引擎更新程序伪装成 Chrome UA用 GetCabFileFromBuff 手工解析 PE 的.rsrc资源段直接定位内嵌的update.cab通过FDICreate/FDICopy配上一组自定义的文件操作回调CUST_FNOPEN、CUST_FNREAD等把 cab 内容解包到内存链表UpdateFilesList中全程不落盘。这段代码展示了典型的内存中解析 PE 资源段技巧是阅读此类 PoC 的常见模式。3.4 触发卷影副本并冻结 Defender 这是攻击最精彩的部分见 FunnyApp.cpp#L2990-L3001 调用的 TriggerWDForVS线程 / 函数做的事ShadowCopyFinderThread通过NtOpenDirectoryObjectNtQueryDirectoryObject枚举\Device目录轮询直到出现新的HarddiskVolumeShadowCopyN对象VSS 快照EICAR 测试文件写入标准 EICAR 病毒特征串注意 rev 反转字符串做简单混淆诱导 Defender 产生动作FreezeVSS注册 Cloud Files 同步根provider 名为IHATEMICROSOFT等待 Defender 查询目录时触发 CfCallbackFetchPlaceHolders 回调批量 oplock对锁文件请求FSCTL_REQUEST_BATCH_OPLOCK一旦 Defender 尝试写入oplock 被打破Defender 实质上被冻住把时间窗口让给攻击者一句话总结用 EICAR 样本把 Defender 引到攻击者设置的Cloud Files 陷阱里让它在快照窗口期内无法动。3.5 关键魔术对象符号链接 oplock 时序 主线程随后做链接接力对应流程图 G→K 节点用 NtCreateDirectoryObjectEx 在当前会话的\Sessions\n\BaseNamedObjects\GUID下建对象目录用NtCreateSymbolicLinkObject在该目录里放一个名为WDUpdateDirectory的符号链接先指向%TEMP%\GUIDL3040-L3056并把解包的更新文件写进去在工作线程里通过 RPC 调用 Proc42_ServerMpUpdateEngineSignature客户端实现在 CallWD接口定义见 windefend.idl传入的目录名走\\?\GLOBALROOT\Sessions\n\BaseNamedObjects\GUID\WDUpdateDirectory这条符号链接之路诱使 SYSTEM 身份的 Defender 服务顺着符号链接去打开攻击者伪造的mpasbase.vdmL3101-L3109主线程用 ReadDirectoryChangesW 监控Definition Updates目录等 Defender 创建新定义更新子目录对新目录里的mpasbase.vdm先请求批量 oplockL3139-L3157Defender 一碰即触发oplock 触发的一瞬间把WDUpdateDirectory符号链接重新指向\Device\HarddiskVolumeShadowCopyN\Windows\System32\Config\SAML3163-L3191。此时 Defender 后续对mpasbase.vdm的打开实际落到的是卷影副本里的SAM 注册表文件——受保护的敏感文件句柄就这样泄漏到了攻击者手里。3.6 事务打开泄漏文件拿到 SAM 句柄 ️htransaction CreateTransaction(...); do { hleakedfile CreateFileTransacted(newdefupdatedirname, GENERIC_READ, ...); } while (hleakedfile INVALID_HANDLE_VALUE || !hleakedfile);见 FunnyApp.cpp#L3204-L3213。用CreateFileTransacted在事务里重试打开直到拿到一个可读的 SAM 句柄随即打印Exploit succeeded.并RollbackTransaction——回滚事务让 Defender 那边不产生实际副作用实现无痕迹读取L3220-L3229。3.7 终局动作DoSpawnShellAsAllUsers 拿到 SAM 句柄后交给 DoSpawnShellAsAllUsers完整提权后半程离线打开 SAM 蜂房通过 offreg.h 中的OROpenHiveByHandle直接把泄漏句柄当注册表 hive 打开读取SAM\Domains\Account的密钥值F与每个用户的V值取 LSA 机密密钥GetLSASecretKey 按经典 bootkey 算法从SYSTEM\Lsa的JD/Skew1/GBG/Data拼出 16 字节密钥解密 NTLM用 AES 解出密码加密密钥UnprotectPasswordEncryptionKey再用 DES 解出每个用户的真实 NTLM 哈希UnprotectNTHash临时改密加载samlib.dll调用SamiChangePasswordUser把某个管理员账户密码临时改成已知值ChangeUserPassword登录并拉 SYSTEMLogonUserEx登录若令牌属于管理员组再批量登录、把完整性级别提到S-1-16-8192L2701-L2714创建同名服务执行本程序自身并传入会话 ID——这正是 3.1 节二次启动分支的来处收尾CreateProcessWithLogonW弹出受害者可见的conhost控制台最后把密码改回去尽量抹平痕迹L2763-L2784。四、漏洞三大核心技巧小结 技巧在攻击中的角色关键代码位置卷影副本VSS枚举拿到 SAM 的只读快照路径绕过文件锁FunnyApp.cpp#L1036-L1350Cloud Files 批量 oplock冻结 Defender制造可控时间窗口FunnyApp.cpp#L1463-L1598NtCreateSymbolicLinkObject让 SYSTEM 服务顺符号链接上钩再指向 SAMFunnyApp.cpp#L3040-L3191事务化文件打开无痕读取敏感句柄FunnyApp.cpp#L3204-L3229五、代码阅读建议路径 如果你是第一次读这类 PoC推荐按下面顺序切入避免一上来就被 3000 行代码劝退先读 README.md了解项目定位读 windefend.idl 与 windefend_h.h#L1356-L1360弄清 Defender 暴露了哪些 RPC 接口、Proc42的签名是什么读 CallWD理解一次 RPC 调用是如何组成的绑定字符串 → 句柄 → NDR 调用最后回到本文第二节的流程图逐节点对照 wmain 通读一遍把goto cleanup风格的全局变量清理L3244-L3311当普通资源释放看即可。六、写在最后从 PoC 看防御思路 ️读懂 BlueHammer 的 wmain 之后你可以带走几条防御侧启发符号链接 SYSTEM 服务的组合是经典提权面高权限服务写入/打开的路径应校验是否为符号链接如FILE_FLAG_OPEN_REPARSE_POINT检测oplock / 文件冻结依赖精确时序对关键路径引入文件完整性与事件审计可显著压缩攻击窗口离线 SAM 解析 bootkey 解密是成熟的取证/攻击技能静态凭据保护如 LSA 密钥派生的每次演进都在抬高这条链路的成本。再次提醒本文仅作代码阅读与防御研究使用。BlueHammer 仓库本身也注明PoC 中存在若干可能影响运行的 bug见 README.md请勿直接在任何真实系统上运行。【免费下载链接】BlueHammerRepository hosting the bluehammer vulnerability项目地址: https://gitcode.com/gh_mirrors/bl/BlueHammer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表