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): 窗口已释放标记
相关内核函数
- 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!__fnDWORDuser32!__xxxClientFreeWindowClassExtraBytes
- Hook
-
窗口创建:
- 注册窗口类,设置
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结构的双重释放
- 在hook中调用
技术细节补充
WNDCLASSEX结构关键成员
typedef struct tagWNDCLASSEXW {
UINT cbSize;
/* ... 其他成员 ... */
int cbWndExtra; // 窗口额外数据大小,必须>0才能触发回调
} WNDCLASSEXW;
SBTrack结构
SBTrack结构由xxxSBTrackInit分配,用于跟踪滚动条状态:
- 包含滚动条窗口和通知窗口指针
- 设置当前窗口为捕获窗口
- 通过
xxxSBTrackLoop处理鼠标消息
关键内存操作
-
窗口释放流程:
- 设置FNID为
0x4000(销毁标记) - 发送
WM_NCDESTROY消息 - 调用
xxxClientFreeWindowClassExtraBytes(用户态回调) - 设置FNID为
0x8000(释放标记)
- 设置FNID为
-
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内核安全机制和开发更有效的防御措施。