Windows之clfs日志提权漏洞
字数 2488 2025-08-19 12:42:28

Windows CLFS日志提权漏洞分析与教学文档

1. CLFS基础概念

1.1 CLFS概述

Common Log File System (CLFS)是Windows提供的高性能、通用日志文件子系统,允许专用客户机应用程序使用,多个客户机可以共享以优化日志访问。

1.2 关键API

CLFSUSER_API HANDLE CreateLogFile(
  [in] LPCWSTR pszLogFileName,
  [in] ACCESS_MASK fDesiredAccess,
  [in] DWORD dwShareMode,
  [in, optional] LPSECURITY_ATTRIBUTES psaLogFile,
  [in] ULONG fCreateDisposition,
  [in] ULONG fFlagsAndAttributes
);

1.3 CLFS数据结构类型

  1. 存储在内核态内存中并附加到对象(如附加到File object的FCB)
  2. 临时存储在用户态或内核态调用者内存中
  3. 持久化存储在磁盘上的基本日志文件(BLF)

2. 关键数据结构

2.1 LOG_BLOCK结构

typedef struct _CLFS_LOG_BLOCK_HEADER {
    UCHAR MajorVersion;
    UCHAR MinorVersion;
    UCHAR Usn;
    CLFS_CLIENT_ID ClientId;
    USHORT TotalSectorCount;
    USHORT ValidSectorCount;
    ULONG Padding;
    ULONG Checksum;  // CRC32校验和
    ULONG Flags;
    CLFS_LSN CurrentLsn;
    CLFS_LSN NextLsn;
    ULONG RecordOffsets[16];  // 日志块中记录的偏移量数组
    ULONG SignaturesOffset;   // 签名数组偏移
} CLFS_LOG_BLOCK_HEADER, *PCLFS_LOG_BLOCK_HEADER;

2.2 BASE_RECORD结构

typedef struct _CLFS_BASE_RECORD_HEADER {
    CLFS_METADATA_RECORD_HEADER hdrBaseRecord;
    CLFS_LOG_ID cidLog;
    ULONGLONG rgClientSymTbl[CLIENT_SYMTBL_SIZE];
    ULONGLONG rgContainerSymTbl[CONTAINER_SYMTBL_SIZE];
    ULONGLONG rgSecuritySymTbl[SHARED_SECURITY_SYMTBL_SIZE];
    ULONG cNextContainer;
    CLFS_CLIENT_ID cNextClient;
    ULONG cFreeContainers;
    ULONG cActiveContainers;  // 当前活跃容器数
    ULONG cbFreeContainers;
    ULONG cbBusyContainers;
    ULONG rgClients[MAX_CLIENTS_DEFAULT];
    ULONG rgContainers[MAX_CONTAINERS_DEFAULT];  // 容器上下文偏移数组
    ULONG cbSymbolZone;  // 关键字段,用于计算新增容器应略过的空间
    ULONG cbSector;
    USHORT bUnused;
    CLFS_LOG_STATE eLogState;
    UCHAR cUsn;
    UCHAR cClients;
} CLFS_BASE_RECORD_HEADER, *PCLFS_BASE_RECORD_HEADER;

2.3 CONTAINER_CONTEXT结构

typedef struct _CLFS_CONTAINER_CONTEXT {
    CLFS_NODE_ID cidNode;
    ULONGLONG cbContainer;
    CLFS_CONTAINER_ID cidContainer;
    CLFS_CONTAINER_ID cidQueue;
    union {
        CClfsContainer* pContainer;  // 关键指针,指向内核对象
        ULONGLONG ullAlignment;
    };
    CLFS_USN usnCurrent;
    CLFS_CONTAINER_STATE eState;
    ULONG cbPrevOffset;
    ULONG cbNextOffset;
} CLFS_CONTAINER_CONTEXT, *PCLFS_CONTAINER_CONTEXT;

2.4 CONTROL_RECORD结构

typedef struct _CLFS_CONTROL_RECORD {
    CLFS_METADATA_RECORD_HEADER hdrControlRecord;
    ULONGLONG ullMagicValue;
    ULONG Version;
    CLFS_EXTEND_STATE eExtendState;  // 扩展状态
    USHORT iExtendBlock;  // 扩展块索引
    USHORT iFlushBlock;   // 正在写入的块索引
    ULONG cNewBlockSectors;  // 新块大小(扇区)
    ULONG cExtendStartSectors;  // 原始块大小
    ULONG cExtendSectors;  // 添加的扇区数
    CLFS_TRUNCATE_CONTEXT cxTruncate;
    ULONG cBlocks;  // 块数量
    ULONG cReserved;
    CLFS_METADATA_BLOCK rgBlocks[6];  // 元数据块数组
} CLFS_CONTROL_RECORD;

2.5 METADATA_BLOCK结构

typedef struct _CLFS_METADATA_BLOCK {
    ULONGLONG pbImage;  // 图像指针
    ULONG cbImage;      // 图像大小
    ULONG cbOffset;     // 偏移量
    CLFS_METADATA_BLOCK_TYPE eBlockType;
    ULONG Padding;
} CLFS_METADATA_BLOCK;

3. 关键函数分析

3.1 编码/解码函数

  • ClfsEncodeBlock: 对日志块进行编码
  • ClfsDecodeBlock: 对日志块进行解码
  • ClfsEncodeBlockPrivate: 内部编码函数
  • CCrc32::ComputeCrc32: 计算CRC32校验和

3.2 容器操作函数

  • CClfsBaseFilePersisted::LoadContainerQ
  • CClfsBaseFilePersisted::RemoveContainer
  • CClfsBaseFilePersisted::FlushImage
  • CClfsBaseFilePersisted::WriteMetadataBlock
  • CClfsBaseFilePersisted::ReadImage
  • CClfsBaseFilePersisted::OpenImage
  • CClfsBaseFilePersisted::ExtendMetadataBlock
  • CClfsBaseFilePersisted::FlushControlRecord
  • CClfsBaseFile::GetControlRecord

4. 漏洞分析

4.1 CVE-2022-24521

漏洞位置: CClfsBaseFilePersisted::LoadContainerQ

漏洞成因:

  1. CLFS_CONTAINER_CONTEXT->cidQueue为-1时,pContainer被置0
  2. 调用RemoveContainer -> FlushImage -> WriteMetadataBlock
  3. ClfsEncodeBlock编码时会将每0x200字节的后两字节写入SignaturesOffset
  4. 通过修改SignaturesOffset使其与pContainer指针相交,编码时覆盖pContainer
  5. 最终FlushImage调用被覆盖的pContainer导致RIP控制

4.2 CVE-2022-30220

漏洞位置: CClfsBaseFilePersisted::ReadImage

漏洞成因:

  1. cBlocks值校验不足(if (cBlocks > 6u))
  2. 分配24和2大小的池空间后执行memmove
  3. cBlocks值异常导致分配0大小空间
  4. 后续操作未初始化空间导致崩溃

4.3 CVE-2022-37969

漏洞位置: CClfsBaseFilePersisted::AllocSymbol

漏洞成因:

  1. 直接使用BLF文件中的cbSymbolZone值无严格边界检查
  2. 通过操作cbSymbolZone可改写container和pContainer指针
  3. 绕过cbSymbolZoneSignaturesOffset的比较验证
  4. memset()导致越界写入,破坏CLFS_CONTAINER_CONTEXT结构

4.4 CVE-2023-23376

漏洞位置: CClfsBaseFilePersisted::OpenImageExtendMetadataBlock

漏洞成因:

  1. OpenImage检查iExtendBlockiFlushBlock应小于6
  2. ExtendMetadataBlock不检查这些索引
  3. 通过修改CLFS_CONTROL_RECORD中的eExtendState等字段
  4. 递增DumpCount使ClfsEncodeBlock覆盖RecordOffsets[0]
  5. 执行被修改的CLFS_CONTROL_RECORD

4.5 CVE-2023-28252

漏洞成因:

  1. WriteMetadataBlock调用ClfsEncodeBlock时校验和置0
  2. ClfsEncodeBlockPrivate检测异常返回错误码但不更新校验和
  3. 元数据块校验和为0绕过OpenImage检查
  4. CreateLogFile调用CheckSecureAccess遍历容器获取pContainer
  5. 构造容器修改偏移,使pContainer指向用户空间构造的虚函数布局

5. 漏洞利用模式总结

  1. 指针覆盖: 通过编码过程覆盖关键指针(如pContainer)
  2. 边界检查缺失: 对关键字段(cbSymbolZone, cBlocks等)缺乏严格验证
  3. 逻辑漏洞: 函数间检查不一致(OpenImageExtendMetadataBlock)
  4. 校验绕过: 利用错误处理路径绕过校验(校验和置0)
  5. 内存破坏: 通过越界写入破坏关键数据结构

6. 防御建议

  1. 对所有从BLF文件读取的字段进行严格验证
  2. 确保相关函数间对同一字段的检查一致
  3. 加强指针操作的验证和保护
  4. 完善错误处理路径,避免绕过安全检查
  5. 对关键数据结构增加保护机制(如Canary)

7. 研究价值

CLFS驱动漏洞系列展示了:

  1. 复杂日志系统的安全挑战
  2. 内核驱动中指针操作的脆弱性
  3. 补丁绕过技术的演变
  4. Windows内核漏洞挖掘的方法论
Windows CLFS日志提权漏洞分析与教学文档 1. CLFS基础概念 1.1 CLFS概述 Common Log File System (CLFS)是Windows提供的高性能、通用日志文件子系统,允许专用客户机应用程序使用,多个客户机可以共享以优化日志访问。 1.2 关键API 1.3 CLFS数据结构类型 存储在内核态内存中并附加到对象(如附加到File object的FCB) 临时存储在用户态或内核态调用者内存中 持久化存储在磁盘上的基本日志文件(BLF) 2. 关键数据结构 2.1 LOG_ BLOCK结构 2.2 BASE_ RECORD结构 2.3 CONTAINER_ CONTEXT结构 2.4 CONTROL_ RECORD结构 2.5 METADATA_ BLOCK结构 3. 关键函数分析 3.1 编码/解码函数 ClfsEncodeBlock : 对日志块进行编码 ClfsDecodeBlock : 对日志块进行解码 ClfsEncodeBlockPrivate : 内部编码函数 CCrc32::ComputeCrc32 : 计算CRC32校验和 3.2 容器操作函数 CClfsBaseFilePersisted::LoadContainerQ CClfsBaseFilePersisted::RemoveContainer CClfsBaseFilePersisted::FlushImage CClfsBaseFilePersisted::WriteMetadataBlock CClfsBaseFilePersisted::ReadImage CClfsBaseFilePersisted::OpenImage CClfsBaseFilePersisted::ExtendMetadataBlock CClfsBaseFilePersisted::FlushControlRecord CClfsBaseFile::GetControlRecord 4. 漏洞分析 4.1 CVE-2022-24521 漏洞位置 : CClfsBaseFilePersisted::LoadContainerQ 漏洞成因 : 当 CLFS_CONTAINER_CONTEXT->cidQueue 为-1时, pContainer 被置0 调用 RemoveContainer -> FlushImage -> WriteMetadataBlock ClfsEncodeBlock 编码时会将每0x200字节的后两字节写入 SignaturesOffset 通过修改 SignaturesOffset 使其与 pContainer 指针相交,编码时覆盖 pContainer 最终 FlushImage 调用被覆盖的 pContainer 导致RIP控制 4.2 CVE-2022-30220 漏洞位置 : CClfsBaseFilePersisted::ReadImage 漏洞成因 : 对 cBlocks 值校验不足( if (cBlocks > 6u) ) 分配24和2大小的池空间后执行 memmove 当 cBlocks 值异常导致分配0大小空间 后续操作未初始化空间导致崩溃 4.3 CVE-2022-37969 漏洞位置 : CClfsBaseFilePersisted::AllocSymbol 漏洞成因 : 直接使用BLF文件中的 cbSymbolZone 值无严格边界检查 通过操作 cbSymbolZone 可改写container和 pContainer 指针 绕过 cbSymbolZone 与 SignaturesOffset 的比较验证 memset() 导致越界写入,破坏 CLFS_CONTAINER_CONTEXT 结构 4.4 CVE-2023-23376 漏洞位置 : CClfsBaseFilePersisted::OpenImage 和 ExtendMetadataBlock 漏洞成因 : OpenImage 检查 iExtendBlock 和 iFlushBlock 应小于6 ExtendMetadataBlock 不检查这些索引 通过修改 CLFS_CONTROL_RECORD 中的 eExtendState 等字段 递增 DumpCount 使 ClfsEncodeBlock 覆盖 RecordOffsets[0] 执行被修改的 CLFS_CONTROL_RECORD 4.5 CVE-2023-28252 漏洞成因 : WriteMetadataBlock 调用 ClfsEncodeBlock 时校验和置0 ClfsEncodeBlockPrivate 检测异常返回错误码但不更新校验和 元数据块校验和为0绕过 OpenImage 检查 CreateLogFile 调用 CheckSecureAccess 遍历容器获取 pContainer 构造容器修改偏移,使 pContainer 指向用户空间构造的虚函数布局 5. 漏洞利用模式总结 指针覆盖 : 通过编码过程覆盖关键指针(如 pContainer ) 边界检查缺失 : 对关键字段( cbSymbolZone , cBlocks 等)缺乏严格验证 逻辑漏洞 : 函数间检查不一致( OpenImage 与 ExtendMetadataBlock ) 校验绕过 : 利用错误处理路径绕过校验(校验和置0) 内存破坏 : 通过越界写入破坏关键数据结构 6. 防御建议 对所有从BLF文件读取的字段进行严格验证 确保相关函数间对同一字段的检查一致 加强指针操作的验证和保护 完善错误处理路径,避免绕过安全检查 对关键数据结构增加保护机制(如Canary) 7. 研究价值 CLFS驱动漏洞系列展示了: 复杂日志系统的安全挑战 内核驱动中指针操作的脆弱性 补丁绕过技术的演变 Windows内核漏洞挖掘的方法论