📢 Gate广场 #NERO发帖挑战# 秀观点赢大奖活动火热开启!
Gate NERO生态周来袭!发帖秀出NERO项目洞察和活动实用攻略,瓜分30,000NERO!
💰️ 15位优质发帖用户 * 2,000枚NERO每人
如何参与:
1️⃣ 调研NERO项目
对NERO的基本面、社区治理、发展目标、代币经济模型等方面进行研究,分享你对项目的深度研究。
2️⃣ 参与并分享真实体验
参与NERO生态周相关活动,并晒出你的参与截图、收益图或实用教程。可以是收益展示、简明易懂的新手攻略、小窍门,也可以是行情点位分析,内容详实优先。
3️⃣ 鼓励带新互动
如果你的帖子吸引到他人参与活动,或者有好友评论“已参与/已交易”,将大幅提升你的获奖概率!
NERO热门活动(帖文需附以下活动链接):
NERO Chain (NERO) 生态周:Gate 已上线 NERO 现货交易,为回馈平台用户,HODLer Airdrop、Launchpool、CandyDrop、余币宝已上线 NERO,邀您体验。参与攻略见公告:https://www.gate.com/announcements/article/46284
高质量帖子Tips:
教程越详细、图片越直观、互动量越高,获奖几率越大!
市场见解独到、真实参与经历、有带新互动者,评选将优先考虑。
帖子需原创,字数不少于250字,且需获得至少3条有效互动
Windows系统级0day漏洞深度剖析与利用技术
微软系统级0day漏洞分析及利用
引言
近期微软安全补丁修复了一个正在被黑客利用的 win32k 提权漏洞。该漏洞主要影响早期 Windows 系统版本,对 Windows 11 似乎无效。本文将深入分析这类漏洞在当前新防护措施不断改进的背景下,攻击者可能如何继续加以利用。我们的分析环境为 Windows Server 2016。
漏洞背景
0day 漏洞指未公开且未修复的安全漏洞,类似于金融市场中的 T+0 交易概念。这类漏洞一旦被恶意利用,往往会造成巨大危害。此次发现的 Windows 系统级 0day 漏洞可让攻击者获得系统完全控制权。
被攻击者控制系统后果严重,包括个人信息泄露、系统崩溃数据丢失、财产损失、恶意程序植入等。对于加密货币用户来说,私钥可能被盗取,数字资产被转移。从更大范围来看,这个漏洞甚至可能影响到整个基于 Web2 基础设施的 Web3 生态系统。
补丁分析
分析补丁代码,问题似乎出在一个对象的引用计数被多次处理。通过查看早期源码注释,我们发现以前的代码只锁定了窗口对象,没有锁定窗口中的菜单对象,这可能导致菜单对象被错误引用。
漏洞验证
分析漏洞函数上下文,我们发现传入 xxxEnableMenuItem() 的菜单通常已在上层函数被锁定,那具体要保护哪个菜单对象?进一步分析 xxxEnableMenuItem 中对菜单对象的处理,发现 MenuItemState 函数返回的菜单有两种可能:窗口主菜单或子菜单(包括子子菜单)。
为验证漏洞,我们构造了一个特殊的四层菜单结构,并设置了一些特定条件来绕过 xxxEnableMenuItem 函数中的检测。在 xxxRedrawTitle 返回用户层时,我们删除菜单 C 和 B 的引用关系,成功释放菜单 C。最后,当内核中 xxxEnableMenuItem 函数返回到 xxxRedrawTitle 函数时,即将引用的菜单 C 对象已失效。
漏洞利用
整体思路
在确定利用方案前,我们通常会进行一些理论分析,以避免在不可行的方案上浪费时间。本次漏洞利用主要考虑了两个方向:
执行 shellcode:参考早期的类似漏洞,但在高版本 Windows 中可能面临一些难以解决的问题。
利用读写原语修改 token:即使在最近两年仍有公开的可参考案例。我们需要重点解决如何在 UAF 内存被重用时首次控制 cbwndextra 为特大值。
因此,我们将整个利用过程分为两部分:如何利用 UAF 漏洞控制 cbwndextra 值,以及控制该值后如何实现稳定的读写原语。
初次数据写入
触发漏洞后,系统不一定会立即崩溃。错误使用被控制内存的窗口对象数据主要发生在 xxxEnableMenuItem 函数的 MNGetPopupFromMenu() 和 xxxMNUpdateShownMenu() 中。
我们使用窗口类 WNDClass 中的窗口名称对象来占用释放的菜单对象内存。关键是找到一个可由我们构建的地址结构中能任意写入数据的位置,哪怕只有一个字节。
最终我们在 xxxRedrawWindow 函数中找到了两个可行方案。考虑到一些限制因素,我们选择了依靠标志位 AND 2 操作的方案,并决定写入 HWNDClass 的 cb-extra 而非窗口对象的 cb-extra。
稳定内存布局
我们设计了至少连续三个 0x250 字节 HWND 对象的内存布局。释放中间对象,用 0x250 字节的 HWNDClass 对象占用。前一个 HWND 对象尾部数据用于通过 xxxRedrawWindow 标志检验,后一个 HWND 对象的菜单对象和 HWNDClass 对象作为最终读写原语媒介。
我们尽量控制窗口对象和 HWNDClass 对象大小一致,并确保窗口对象扩展数据足够大。通过堆内存中泄露的内核句柄地址,我们可以精确判断申请的窗口对象是否按预期顺序排列。
读写原语实现
任意读原语仍使用 GetMenuBarInfo()。任意写原语则使用 SetClassLongPtr()。除替换 TOKEN 的写入操作依赖第二个窗口的 class 对象外,其他写入都利用第一个窗口对象的 class 对象使用偏移来实现。
总结
win32k 漏洞由来已久,但微软正在用 Rust 重构相关内核代码,未来新系统可能杜绝此类漏洞。
本次漏洞利用过程不算困难,主要难点在于如何控制首次写入。漏洞仍严重依赖桌面堆句柄地址泄露,这对老旧系统仍是安全隐患。
该漏洞的发现可能得益于更完善的代码覆盖率检测。一旦系统 API 能在目标函数执行路径到达最深处漏洞点,且窗口对象处于多重嵌套引用状态,fuzz 测试就可能发现这个漏洞。
对于漏洞利用检测,除了关注漏洞触发函数的关键点,还应关注异常的内存布局和对窗口或窗口类额外数据的非常规偏移读写,这可能有助于发现同类型漏洞。