CVE-2018-8453内核漏洞分析
字数 2506 2025-08-29 08:32:24

CVE-2018-8453 Windows内核提权漏洞深入分析与利用

漏洞概述

CVE-2018-8453是卡巴斯基实验室在2018年8月发现的Windows提权0day漏洞,该漏洞存在于Windows窗口管理和图形设备接口组件(win32kfull.sys)中。攻击者可以利用此漏洞将低权限用户账户(users)提升至系统权限(system)。

漏洞本质是一个Use-After-Free(UAF)问题,源于win32kfull!NtUserSetWindowFNID函数在设置窗口对象FNID时未能正确验证窗口对象是否已被释放,导致可以对已释放的窗口(FNID_FREED:0x8000)设置新的FNID。

漏洞背景

窗口FNID机制

FNID(窗口功能标识符)是Windows内核用于标识窗口类型的内部机制:

  • FNID_SCROLLBAR (0x029A): 滚动条窗口
  • FNID_BUTTON (0x02A1): 按钮窗口
  • FNID_DESTROY (0x4000): 窗口销毁标记
  • FNID_FREED (0x8000): 窗口已释放标记

相关内核函数

  1. NtUserSetWindowFNID: 用户态设置窗口FNID的系统调用
  2. xxxDestroyWindow/xxxFreeWindow: 窗口销毁相关函数
  3. xxxSBTrackInit/xxxSBTrackLoop: 滚动条跟踪相关函数

漏洞详细分析

根本原因

漏洞的根本原因是win32kfull!NtUserSetWindowFNID函数在设置窗口FNID时缺少对窗口是否正在被销毁的检查。补丁中新增了IsWindowBeingDestroyed函数调用来修复此问题。

漏洞触发条件

要成功修改窗口FNID需要满足以下条件之一:

  1. FNID为空(刚创建的窗口)
  2. FNID为用户注册窗口类产生的窗口(一直未设置FNID)
  3. sysShadow窗口(用于阴影效果,FNID为空)

漏洞利用关键点

  1. FNID修改限制:

    • 只能修改FNID为≤0x2A1的值
    • 或修改为>0x3FFF的值(0x4000或0x8000)
  2. 关键窗口消息:

    • WM_LBUTTONDOWN: 触发滚动条跟踪
    • WM_NCDESTROY: 窗口销毁前最后消息
    • WM_CANCELMODE: 取消滚动条跟踪
  3. 关键回调函数:

    • __fnDWORD: 用于窗口销毁回调
    • __xxxClientFreeWindowClassExtraBytes: 用于释放窗口额外类数据

漏洞利用流程

完整的漏洞利用过程可分为以下步骤:

  1. Hook设置:

    • Hook KernelCallbackTable中的两个回调:
      • user32!__fnDWORD
      • user32!__xxxClientFreeWindowClassExtraBytes
  2. 窗口创建:

    • 注册窗口类,设置WNDCLASSEXW.cbWndExtra=4
    • 创建主窗口作为父窗口
    • 创建滚动条窗口(ScrollBar)
  3. 触发滚动条跟踪:

    • 发送WM_LBUTTONDOWN消息
    • 系统调用xxxSBTrackInit初始化SBTrack结构
    • 进入xxxSBTrackLoop处理鼠标消息
  4. 窗口销毁阶段:

    • fnDWORD_hook中调用DestroyWindow销毁主窗口
    • 触发xxxFreeWindow函数执行
    • 设置FNID为0x4000(销毁标记)
    • 设置FNID为0x8000(释放标记)
  5. FNID修改:

    • 通过xxxClientFreeWindowClassExtraBytes回调进入hook函数
    • 在hook中调用NtUserSetWindowFNID修改FNID为0x82A1
  6. UAF触发:

    • 创建新窗口并调用SetCapture设置捕获窗口
    • 主窗口引用计数归零,彻底释放窗口对象
    • 再次进入xxxFreeWindow,此时FNID为0x82A2
    • 通过SfnDWORD回调进入hook函数
  7. 双重释放:

    • 在hook中调用SendMessage(g_hSBWNDNew, WM_CANCELMODE)
    • 触发xxxEndScroll释放pSBTrack
    • 流程返回内核后xxxSBTrackInit再次释放SBTrack
    • 造成SBTrack结构的双重释放

技术细节补充

WNDCLASSEX结构关键成员

typedef struct tagWNDCLASSEXW {
    UINT     cbSize;
    /* ... 其他成员 ... */
    int      cbWndExtra;    // 窗口额外数据大小,必须>0才能触发回调
} WNDCLASSEXW;

SBTrack结构

SBTrack结构由xxxSBTrackInit分配,用于跟踪滚动条状态:

  • 包含滚动条窗口和通知窗口指针
  • 设置当前窗口为捕获窗口
  • 通过xxxSBTrackLoop处理鼠标消息

关键内存操作

  1. 窗口释放流程:

    • 设置FNID为0x4000(销毁标记)
    • 发送WM_NCDESTROY消息
    • 调用xxxClientFreeWindowClassExtraBytes(用户态回调)
    • 设置FNID为0x8000(释放标记)
  2. FNID修改时机:

    • 必须在设置0x8000标记后
    • 通过用户态hook函数修改
    • 修改为0x82A1(FNID_FREED | FNID_BUTTON)

防御与检测

  1. 补丁修复:

    • 微软通过添加IsWindowBeingDestroyed检查修复
    • 确保不能对正在销毁的窗口修改FNID
  2. 检测指标:

    • 异常FNID修改操作
    • 对FNID_FREED窗口的FNID设置尝试
    • 异常的滚动条跟踪操作序列
  3. 缓解措施:

    • 启用控制流防护(CFG)
    • 限制低权限用户的窗口消息处理能力
    • 监控win32kfull.sys中的异常行为

总结

CVE-2018-8453是一个典型的Windows内核UAF漏洞,通过精心构造的窗口操作序列和FNID修改,攻击者可以实现权限提升。漏洞利用涉及多个Windows消息处理机制和内核对象生命周期管理,展示了Windows图形子系统复杂交互中潜在的安全问题。理解此漏洞有助于深入分析Windows内核安全机制和开发更有效的防御措施。

CVE-2018-8453 Windows内核提权漏洞深入分析与利用 漏洞概述 CVE-2018-8453是卡巴斯基实验室在2018年8月发现的Windows提权0day漏洞,该漏洞存在于Windows窗口管理和图形设备接口组件(win32kfull.sys)中。攻击者可以利用此漏洞将低权限用户账户(users)提升至系统权限(system)。 漏洞本质是一个Use-After-Free(UAF)问题,源于win32kfull!NtUserSetWindowFNID函数在设置窗口对象FNID时未能正确验证窗口对象是否已被释放,导致可以对已释放的窗口(FNID_ FREED:0x8000)设置新的FNID。 漏洞背景 窗口FNID机制 FNID(窗口功能标识符)是Windows内核用于标识窗口类型的内部机制: FNID_SCROLLBAR (0x029A): 滚动条窗口 FNID_BUTTON (0x02A1): 按钮窗口 FNID_DESTROY (0x4000): 窗口销毁标记 FNID_FREED (0x8000): 窗口已释放标记 相关内核函数 NtUserSetWindowFNID : 用户态设置窗口FNID的系统调用 xxxDestroyWindow/xxxFreeWindow : 窗口销毁相关函数 xxxSBTrackInit/xxxSBTrackLoop : 滚动条跟踪相关函数 漏洞详细分析 根本原因 漏洞的根本原因是 win32kfull!NtUserSetWindowFNID 函数在设置窗口FNID时缺少对窗口是否正在被销毁的检查。补丁中新增了 IsWindowBeingDestroyed 函数调用来修复此问题。 漏洞触发条件 要成功修改窗口FNID需要满足以下条件之一: FNID为空(刚创建的窗口) FNID为用户注册窗口类产生的窗口(一直未设置FNID) sysShadow窗口(用于阴影效果,FNID为空) 漏洞利用关键点 FNID修改限制 : 只能修改FNID为≤0x2A1的值 或修改为>0x3FFF的值(0x4000或0x8000) 关键窗口消息 : WM_LBUTTONDOWN : 触发滚动条跟踪 WM_NCDESTROY : 窗口销毁前最后消息 WM_CANCELMODE : 取消滚动条跟踪 关键回调函数 : __fnDWORD : 用于窗口销毁回调 __xxxClientFreeWindowClassExtraBytes : 用于释放窗口额外类数据 漏洞利用流程 完整的漏洞利用过程可分为以下步骤: Hook设置 : Hook KernelCallbackTable 中的两个回调: user32!__fnDWORD user32!__xxxClientFreeWindowClassExtraBytes 窗口创建 : 注册窗口类,设置 WNDCLASSEXW.cbWndExtra=4 创建主窗口作为父窗口 创建滚动条窗口(ScrollBar) 触发滚动条跟踪 : 发送 WM_LBUTTONDOWN 消息 系统调用 xxxSBTrackInit 初始化 SBTrack 结构 进入 xxxSBTrackLoop 处理鼠标消息 窗口销毁阶段 : 在 fnDWORD_hook 中调用 DestroyWindow 销毁主窗口 触发 xxxFreeWindow 函数执行 设置FNID为 0x4000 (销毁标记) 设置FNID为 0x8000 (释放标记) FNID修改 : 通过 xxxClientFreeWindowClassExtraBytes 回调进入hook函数 在hook中调用 NtUserSetWindowFNID 修改FNID为 0x82A1 UAF触发 : 创建新窗口并调用 SetCapture 设置捕获窗口 主窗口引用计数归零,彻底释放窗口对象 再次进入 xxxFreeWindow ,此时FNID为 0x82A2 通过 SfnDWORD 回调进入hook函数 双重释放 : 在hook中调用 SendMessage(g_hSBWNDNew, WM_CANCELMODE) 触发 xxxEndScroll 释放 pSBTrack 流程返回内核后 xxxSBTrackInit 再次释放 SBTrack 造成 SBTrack 结构的双重释放 技术细节补充 WNDCLASSEX结构关键成员 SBTrack结构 SBTrack 结构由 xxxSBTrackInit 分配,用于跟踪滚动条状态: 包含滚动条窗口和通知窗口指针 设置当前窗口为捕获窗口 通过 xxxSBTrackLoop 处理鼠标消息 关键内存操作 窗口释放流程 : 设置FNID为 0x4000 (销毁标记) 发送 WM_NCDESTROY 消息 调用 xxxClientFreeWindowClassExtraBytes (用户态回调) 设置FNID为 0x8000 (释放标记) FNID修改时机 : 必须在设置 0x8000 标记后 通过用户态hook函数修改 修改为 0x82A1 (FNID_ FREED | FNID_ BUTTON) 防御与检测 补丁修复 : 微软通过添加 IsWindowBeingDestroyed 检查修复 确保不能对正在销毁的窗口修改FNID 检测指标 : 异常FNID修改操作 对FNID_ FREED窗口的FNID设置尝试 异常的滚动条跟踪操作序列 缓解措施 : 启用控制流防护(CFG) 限制低权限用户的窗口消息处理能力 监控win32kfull.sys中的异常行为 总结 CVE-2018-8453是一个典型的Windows内核UAF漏洞,通过精心构造的窗口操作序列和FNID修改,攻击者可以实现权限提升。漏洞利用涉及多个Windows消息处理机制和内核对象生命周期管理,展示了Windows图形子系统复杂交互中潜在的安全问题。理解此漏洞有助于深入分析Windows内核安全机制和开发更有效的防御措施。