CVE-2021-31956提权漏洞分析与利用
字数 1540 2025-08-25 22:58:28

CVE-2021-31956 Windows NTFS提权漏洞分析与利用指南

漏洞概述

CVE-2021-31956是Windows NTFS文件系统驱动(NTFS.sys)中的一个提权漏洞,属于整数溢出导致的条件判断绕过漏洞,最终可导致内核缓冲区溢出。该漏洞允许低权限用户提升至SYSTEM权限。

前置知识

NTFS文件系统基础

  • NTFS是Windows默认文件系统,具有错误预警、磁盘自我修复和日志功能
  • 采用簇(cluster)作为存储单位
  • 使用扩展属性(Extended Attributes, EA)存储额外文件信息

关键概念

  • EA(Extended Attribute): 文件扩展属性,每个EA块需要32位对齐
  • 对齐计算: padding = ((ea_block_size + 3) & 0xFFFFFFFC) - ea_block_size
  • 相关系统调用: NtSetEaFileNtQueryEaFile

漏洞分析

漏洞函数

漏洞位于NtfsQueryEaUserEaList函数中,该函数处理文件扩展属性列表并将其存储到缓冲区。

关键结构体

typedef struct _FILE_FULL_EA_INFORMATION {
    ULONG  NextEntryOffset;  // 下一个同类型结构的偏移,最后一个为0
    UCHAR  Flags;
    UCHAR  EaNameLength;     // EaName数组的长度
    USHORT EaValueLength;    // 每个EA值的长度
    CHAR   EaName[1];        // 属性名
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;

typedef struct _FILE_GET_EA_INFORMATION {
    ULONG NextEntryOffset;
    UCHAR EaNameLength;
    CHAR  EaName[1];
} FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION;

漏洞点

漏洞发生在以下检查处:

ea_block_size <= User_Buffer_Length - padding

其中:

  • ea_block_size = ea_block->EaValueLength + ea_block->EaNameLength + 9
  • 三个参数都是无符号32位整数(ui32)

漏洞原理

  1. User_Buffer_Length小于padding时,减法会导致无符号整数下溢
  2. 下溢结果会非常大,绕过条件检查
  3. 导致memmove操作时发生缓冲区溢出

触发条件

通过精心构造EA属性,使得:

  1. 第一次循环时padding=0,正常通过检查
  2. 第二次循环时User_Buffer_Length减小,padding增大
  3. 导致User_Buffer_Length - padding下溢,绕过检查

漏洞利用

利用步骤

  1. 创建恶意文件:创建带有精心构造EA属性的文件
  2. 触发漏洞:通过NtQueryEaFile触发漏洞
  3. 堆布局:利用Windows通知设施(WNF)进行内核堆布局
  4. 内存操作:实现任意内存读写
  5. 提权:替换进程token

WNF利用技术

Windows Notification Facility(WNF)用于实现任意内存读写原语:

  1. 创建WNF对象NtCreateWnfStateName
  2. 写入数据NtUpdateWnfStateData
  3. 读取数据NtQueryWnfStateData
  4. 删除对象NtDeleteWnfStateData

完整利用流程

  1. 通过漏洞溢出覆盖相邻WNF_STATE_DATA的DataSizeAllocateSize成员
  2. 使用NtQueryWnfStateData读取和NtUpdateWnfStateData修改数据
  3. 修改邻近WNF_NAME_INSTANCE结构的StateData指针为任意内存地址
  4. 实现任意地址读写
  5. 遍历进程链表找到SYSTEM进程
  6. 读取SYSTEM进程的token
  7. 修改当前进程token为SYSTEM token完成提权

漏洞验证代码

设置EA属性

NTSTATUS SetEaFileExample(HANDLE hFile) {
    FILE_FULL_EA_INFORMATION eaInfo;
    IO_STATUS_BLOCK ioStatus;
    NTSTATUS status;
    
    // 设置EA属性
    eaInfo.NextEntryOffset = 0;
    eaInfo.Flags = 0;
    eaInfo.EaNameLength = 5;  // "Malic"
    eaInfo.EaValueLength = 4; // 精心构造的值
    strcpy(eaInfo.EaName, "Malic");
    
    // 设置EA值
    DWORD value = 0x41414141;
    memcpy(eaInfo.EaName + eaInfo.EaNameLength + 1, &value, sizeof(value));
    
    // 调用NtSetEaFile
    status = NtSetEaFile(hFile, &ioStatus, &eaInfo, sizeof(eaInfo));
    return status;
}

触发漏洞

NTSTATUS TriggerVulnerability(HANDLE hFile) {
    IO_STATUS_BLOCK ioStatus;
    NTSTATUS status;
    CHAR buffer[0x1000];
    
    // 调用NtQueryEaFile触发漏洞
    status = NtQueryEaFile(
        hFile, 
        &ioStatus, 
        buffer, 
        sizeof(buffer), 
        FALSE, 
        NULL, 
        0, 
        NULL, 
        TRUE
    );
    
    return status;
}

防御措施

  1. 应用微软发布的补丁
  2. 监控异常的文件系统操作
  3. 限制低权限用户对文件系统驱动的高危操作

总结

CVE-2021-31956是一个典型的NTFS驱动整数溢出漏洞,通过精心构造EA属性可以绕过安全检查,导致内核缓冲区溢出。结合WNF技术可以实现任意内存读写,最终完成权限提升。理解此漏洞有助于深入分析Windows内核安全机制和文件系统驱动的潜在风险。

CVE-2021-31956 Windows NTFS提权漏洞分析与利用指南 漏洞概述 CVE-2021-31956是Windows NTFS文件系统驱动(NTFS.sys)中的一个提权漏洞,属于整数溢出导致的条件判断绕过漏洞,最终可导致内核缓冲区溢出。该漏洞允许低权限用户提升至SYSTEM权限。 前置知识 NTFS文件系统基础 NTFS是Windows默认文件系统,具有错误预警、磁盘自我修复和日志功能 采用簇(cluster)作为存储单位 使用扩展属性(Extended Attributes, EA)存储额外文件信息 关键概念 EA(Extended Attribute) : 文件扩展属性,每个EA块需要32位对齐 对齐计算 : padding = ((ea_block_size + 3) & 0xFFFFFFFC) - ea_block_size 相关系统调用 : NtSetEaFile 和 NtQueryEaFile 漏洞分析 漏洞函数 漏洞位于 NtfsQueryEaUserEaList 函数中,该函数处理文件扩展属性列表并将其存储到缓冲区。 关键结构体 漏洞点 漏洞发生在以下检查处: 其中: ea_block_size = ea_block->EaValueLength + ea_block->EaNameLength + 9 三个参数都是无符号32位整数(ui32) 漏洞原理 当 User_Buffer_Length 小于 padding 时,减法会导致无符号整数下溢 下溢结果会非常大,绕过条件检查 导致 memmove 操作时发生缓冲区溢出 触发条件 通过精心构造EA属性,使得: 第一次循环时 padding=0 ,正常通过检查 第二次循环时 User_Buffer_Length 减小, padding 增大 导致 User_Buffer_Length - padding 下溢,绕过检查 漏洞利用 利用步骤 创建恶意文件 :创建带有精心构造EA属性的文件 触发漏洞 :通过 NtQueryEaFile 触发漏洞 堆布局 :利用Windows通知设施(WNF)进行内核堆布局 内存操作 :实现任意内存读写 提权 :替换进程token WNF利用技术 Windows Notification Facility(WNF)用于实现任意内存读写原语: 创建WNF对象 : NtCreateWnfStateName 写入数据 : NtUpdateWnfStateData 读取数据 : NtQueryWnfStateData 删除对象 : NtDeleteWnfStateData 完整利用流程 通过漏洞溢出覆盖相邻WNF_ STATE_ DATA的 DataSize 和 AllocateSize 成员 使用 NtQueryWnfStateData 读取和 NtUpdateWnfStateData 修改数据 修改邻近WNF_ NAME_ INSTANCE结构的 StateData 指针为任意内存地址 实现任意地址读写 遍历进程链表找到SYSTEM进程 读取SYSTEM进程的token 修改当前进程token为SYSTEM token完成提权 漏洞验证代码 设置EA属性 触发漏洞 防御措施 应用微软发布的补丁 监控异常的文件系统操作 限制低权限用户对文件系统驱动的高危操作 总结 CVE-2021-31956是一个典型的NTFS驱动整数溢出漏洞,通过精心构造EA属性可以绕过安全检查,导致内核缓冲区溢出。结合WNF技术可以实现任意内存读写,最终完成权限提升。理解此漏洞有助于深入分析Windows内核安全机制和文件系统驱动的潜在风险。