Windows内核利用小总结
字数 2436 2025-08-18 11:36:48

Windows内核利用技术深度解析

1. 令牌(Token)提权技术

1.1 基本原理

Windows进程的访问权限由令牌(Token)控制,存储在EPROCESS结构的Token字段中。通过将System进程的Token替换到目标进程的EPROCESS结构中,可以实现提权。

1.2 关键实现步骤

  1. 定位System进程和目标进程的EPROCESS结构
  2. 获取System进程的Token值
  3. 修改目标进程EPROCESS中的Token字段
  4. 注意Token在EPROCESS中的偏移量随Windows版本变化(如1809版本偏移为0x360)

1.3 Token结构特点

Token是一个_EX_FAST_REF结构,由于内存对齐要求,指向内核对象的指针最低4位总是0。

2. PreviousMode利用技术

2.1 PreviousMode作用机制

  • UserMode(1): 进行地址验证,防止用户态写入内核内存
  • KernelMode(0): 跳过地址验证,允许任意内核内存写入

2.2 利用条件

需要能够修改KTHREAD结构中的PreviousMode字段,将其从UserMode改为KernelMode。

3. Windows内核池利用技术

3.1 池分配基础

主要分配函数:

void *ExAllocatePoolWithTag(POOL_TYPE PoolType, size_t NumberOfBytes, unsigned int Tag);
void ExFreePoolWithTag(void *P, unsigned int Tag);

3.2 POOL_TYPE类型

类型 描述
NonPagedPool 0 不可分页内存
PagedPool 1 可分页内存
NonPagedPoolMustSucceed 2 必须成功分配
NonPagedPoolCacheAligned 4 缓存对齐的非分页池
PoolQuota 8 使用配额机制
NonPagedPoolNx 0x200 不可执行的非分页池

3.3 POOL_HEADER结构

struct POOL_HEADER {
    char PreviousSize;    // 前一个块大小/16
    char PoolIndex;        // PoolDescriptor数组索引
    char BlockSize;        // 当前块大小/16
    char PoolType;         // 池类型信息
    int PoolTag;           // 池标签
    Ptr64 ProcessBilled;   // 指向分配进程的KPROCESS指针
};

3.4 利用技术演变

  1. Win7及之前:覆盖ProcessBilled指针实现任意指针解引用
  2. Win8引入:ExpPoolQuotaCookie保护机制,验证KPROCESS指针有效性
  3. Win10 19H1后:引入Segment Heap,改变了POOL_HEADER利用方式

4. Segment Heap利用技术

4.1 段堆后端类型

  1. Segment Backend:分配128KB-7GB内存块
  2. Variable Size Backend:分配512B-128KB内存块
  3. Low Fragmentation Heap Backend:分配1B-512B内存块
  4. Large Alloc:超大内存分配

4.2 关键结构

  • _SEGMENT_HEAP:段堆主结构
  • _HEAP_PAGE_SEGMENT:段头结构
  • _HEAP_PAGE_RANGE_DESCRIPTOR:页范围描述符

4.3 幽灵块(Ghost Chunk)技术

  1. 通过堆溢出修改下一个块的POOL_HEADER
  2. 设置PoolType中的CacheAligned位
  3. 控制PreviousSize字段指向伪造块
  4. 在合法块中间创建虚假块(幽灵块)

4.4 利用步骤

  1. 堆喷创建合适的内存布局
  2. 触发漏洞覆盖POOL_HEADER
  3. 创建幽灵块实现UAF
  4. 通过管道属性操作实现任意读写

5. I/O Ring利用技术

5.1 I/O Ring基本结构

typedef struct _IORING_OBJECT {
    USHORT Type;
    USHORT Size;
    NT_IORING_INFO Info;
    PSECTION SectionObject;
    PVOID KernelMappedBase;
    PMDL Mdl;
    PVOID MdlMappedBase;
    ULONG_PTR ViewSize;
    ULONG SubmitInProgress;
    PVOID IoRingEntryLock;
    PVOID EntriesCompleted;
    PVOID EntriesSubmitted;
    KEVENT RingEvent;
    PVOID EntriesPending;
    ULONG BuffersRegistered;
    PIORING_BUFFER_INFO BufferArray;  // RegBuffers
    ULONG FilesRegistered;
    PHANDLE FileHandleArray;
} IORING_OBJECT;

5.2 利用原理

  1. 通过漏洞覆盖IoRing->RegBuffers指向伪造缓冲区数组
  2. 使用伪造数组指定内核地址进行读写
  3. 22H2后需要使用IOP_MC_BUFFER_ENTRY结构

5.3 IOP_MC_BUFFER_ENTRY结构

typedef struct _IOP_MC_BUFFER_ENTRY {
    USHORT Type;
    USHORT Reserved;
    ULONG Size;
    ULONG ReferenceCount;
    ULONG Flags;
    _LIST_ENTRY GlobalDataLink;
    PVOID Address;        // 目标地址
    ULONG Length;         // 长度
    CHAR AccessMode;
    ULONG MdlRef;
    struct _MDL* Mdl;
    KEVENT MdlRundownEvent;
    PULONG64 PfnArray;
    BYTE PageNodes[1];
} IOP_MC_BUFFER_ENTRY;

5.4 典型利用流程(CVE-2023-21768)

  1. 创建I/O Ring和命名管道
  2. 获取I/O Ring对象地址
  3. 覆盖RegBuffers和RegBuffersCount
  4. 构造伪造的IOP_MC_BUFFER_ENTRY数组
  5. 通过BuildIoRingReadFile/BuildIoRingWriteFile进行内核读写
  6. 替换目标进程Token实现提权

6. 防御机制与绕过技术

6.1 主要防御机制

  1. ExpPoolQuotaCookie:保护ProcessBilled指针
  2. NonPagedPoolNx:不可执行内存保护
  3. Segment Heap:改变内存管理方式
  4. 22H2的IOP_MC_BUFFER_ENTRY:更严格的缓冲区验证

6.2 绕过技术

  1. 利用PoolType中的CacheAligned位
  2. 通过幽灵块实现UAF
  3. 结合管道属性操作实现任意读写
  4. 使用I/O Ring机制实现内核内存操作

7. 实用工具与技术

7.1 关键API

  1. NtQuerySystemInformation:获取系统信息(如SystemBigPoolInformation)
  2. NtFsControlFile:操作管道属性
  3. CreateIoRing:创建I/O Ring
  4. BuildIoRingReadFile/BuildIoRingWriteFile:I/O Ring读写操作

7.2 调试命令

  1. dt nt!_EPROCESS:查看EPROCESS结构
  2. dt nt!_SEGMENT_HEAP:查看段堆结构
  3. dt nt!_HEAP_SEG_CONTEXT:查看段后端上下文

8. 总结与趋势

Windows内核利用技术随着防御机制的增强而不断演进:

  1. 从直接的Token替换到复杂的池利用
  2. 从简单的堆溢出到幽灵块技术
  3. 从传统的池操作到I/O Ring等新机制利用
  4. 利用原语从任意读写发展为更精细的内存操作

未来内核利用可能会更多关注:

  1. 新引入的内核子系统
  2. 硬件特性与内核的交互
  3. 虚拟化环境下的内核行为
  4. 跨进程/跨会话的内核对象操作
Windows内核利用技术深度解析 1. 令牌(Token)提权技术 1.1 基本原理 Windows进程的访问权限由令牌(Token)控制,存储在EPROCESS结构的Token字段中。通过将System进程的Token替换到目标进程的EPROCESS结构中,可以实现提权。 1.2 关键实现步骤 定位System进程和目标进程的EPROCESS结构 获取System进程的Token值 修改目标进程EPROCESS中的Token字段 注意Token在EPROCESS中的偏移量随Windows版本变化(如1809版本偏移为0x360) 1.3 Token结构特点 Token是一个_ EX_ FAST_ REF结构,由于内存对齐要求,指向内核对象的指针最低4位总是0。 2. PreviousMode利用技术 2.1 PreviousMode作用机制 UserMode(1): 进行地址验证,防止用户态写入内核内存 KernelMode(0): 跳过地址验证,允许任意内核内存写入 2.2 利用条件 需要能够修改KTHREAD结构中的PreviousMode字段,将其从UserMode改为KernelMode。 3. Windows内核池利用技术 3.1 池分配基础 主要分配函数: 3.2 POOL_ TYPE类型 | 类型 | 值 | 描述 | |------|----|------| | NonPagedPool | 0 | 不可分页内存 | | PagedPool | 1 | 可分页内存 | | NonPagedPoolMustSucceed | 2 | 必须成功分配 | | NonPagedPoolCacheAligned | 4 | 缓存对齐的非分页池 | | PoolQuota | 8 | 使用配额机制 | | NonPagedPoolNx | 0x200 | 不可执行的非分页池 | 3.3 POOL_ HEADER结构 3.4 利用技术演变 Win7及之前 :覆盖ProcessBilled指针实现任意指针解引用 Win8引入 :ExpPoolQuotaCookie保护机制,验证KPROCESS指针有效性 Win10 19H1后 :引入Segment Heap,改变了POOL_ HEADER利用方式 4. Segment Heap利用技术 4.1 段堆后端类型 Segment Backend :分配128KB-7GB内存块 Variable Size Backend :分配512B-128KB内存块 Low Fragmentation Heap Backend :分配1B-512B内存块 Large Alloc :超大内存分配 4.2 关键结构 _SEGMENT_HEAP :段堆主结构 _HEAP_PAGE_SEGMENT :段头结构 _HEAP_PAGE_RANGE_DESCRIPTOR :页范围描述符 4.3 幽灵块(Ghost Chunk)技术 通过堆溢出修改下一个块的POOL_ HEADER 设置PoolType中的CacheAligned位 控制PreviousSize字段指向伪造块 在合法块中间创建虚假块(幽灵块) 4.4 利用步骤 堆喷创建合适的内存布局 触发漏洞覆盖POOL_ HEADER 创建幽灵块实现UAF 通过管道属性操作实现任意读写 5. I/O Ring利用技术 5.1 I/O Ring基本结构 5.2 利用原理 通过漏洞覆盖IoRing->RegBuffers指向伪造缓冲区数组 使用伪造数组指定内核地址进行读写 22H2后需要使用IOP_ MC_ BUFFER_ ENTRY结构 5.3 IOP_ MC_ BUFFER_ ENTRY结构 5.4 典型利用流程(CVE-2023-21768) 创建I/O Ring和命名管道 获取I/O Ring对象地址 覆盖RegBuffers和RegBuffersCount 构造伪造的IOP_ MC_ BUFFER_ ENTRY数组 通过BuildIoRingReadFile/BuildIoRingWriteFile进行内核读写 替换目标进程Token实现提权 6. 防御机制与绕过技术 6.1 主要防御机制 ExpPoolQuotaCookie:保护ProcessBilled指针 NonPagedPoolNx:不可执行内存保护 Segment Heap:改变内存管理方式 22H2的IOP_ MC_ BUFFER_ ENTRY:更严格的缓冲区验证 6.2 绕过技术 利用PoolType中的CacheAligned位 通过幽灵块实现UAF 结合管道属性操作实现任意读写 使用I/O Ring机制实现内核内存操作 7. 实用工具与技术 7.1 关键API NtQuerySystemInformation :获取系统信息(如SystemBigPoolInformation) NtFsControlFile :操作管道属性 CreateIoRing :创建I/O Ring BuildIoRingReadFile / BuildIoRingWriteFile :I/O Ring读写操作 7.2 调试命令 dt nt!_EPROCESS :查看EPROCESS结构 dt nt!_SEGMENT_HEAP :查看段堆结构 dt nt!_HEAP_SEG_CONTEXT :查看段后端上下文 8. 总结与趋势 Windows内核利用技术随着防御机制的增强而不断演进: 从直接的Token替换到复杂的池利用 从简单的堆溢出到幽灵块技术 从传统的池操作到I/O Ring等新机制利用 利用原语从任意读写发展为更精细的内存操作 未来内核利用可能会更多关注: 新引入的内核子系统 硬件特性与内核的交互 虚拟化环境下的内核行为 跨进程/跨会话的内核对象操作