安全研究团队 SAFA 近期公开了针对 Avast Antivirus 与 AVG Antivirus 沙盒内核驱动漏洞的完整利用链分析。这处编号为 CVE-2025-13032 的高危缺陷,暴露出一个极具讽刺意味的架构悖论:攻击者只有先主动触发沙盒规则被关进隔离区,才能拿到触碰底层特权驱动的钥匙,进而在 Windows 11 环境下顺藤摸瓜将本地普通权限一路拉升至操作系统最顶层的 SYSTEM 特权。
杀毒软件本该是终端防御的最厚装甲,当装甲自身暴露出直接由用户态诱导的竞态裂隙时,防御机制就变成了攻击者最顺手的跳板。围绕这处漏洞的定级,厂商 Gen Digital 依据最新的 CVSS v4.0 标准直接打出了 9.9 分的危急评级,而美国国家漏洞数据库 NVD 在 CVSS v3.1 体系下给出的分数则是 7.8 分。两种定级分歧的背后,本质上是对本地利用门槛与特权失控后果的评估差异,但无论数字如何变化,安全边界在内核层被击穿的事实已经摆在眼前。
沙盒反噬:关进笼子反得钥匙
根据 SAFA 披露的时间线,研究团队早在 2025 年 3 月 14 日便向厂商提交了安全报告,漏洞于 2025 年 11 月 11 日获得 CVE 编号分配,其深度技术分析在 2025 年 12 月 1 日公开第一部分后,于 2026 年 9 月 18 日完成了核心利用链的完整推演。在整个挖掘周期内,研究人员在 Avast 沙盒驱动 aswSnx.sys 中一共挖出了 4 个内核堆溢出缺陷以及 2 个拒绝服务隐患。
这起漏洞在官方分类中被归入 CWE-367,也就是典型的检查到使用(TOCTOU)时间差竞态条件。漏洞产生的根源极为经典却又屡禁不止:Avast 的内核驱动在处理低权限传入的 _UNICODE_STRING 结构体时,虽然调用了 ProbeForRead 对用户态内存进行检查,但在后续的代码逻辑里,驱动对结构体中的 Length 长度字段执行了两次独立的内存读取。
// 第一次获取长度用于在内核分页池开辟缓冲区
PoolWithTag = ExAllocatePoolWithTag(PagedPool, unicodestring_user->Length + 16, ...);
// 第二次获取长度直接作为内存拷贝的大小参数
Length = unicodestring_user->Length;
memmove(..., Buffer, Length);
攻击者利用这种微小的时间差,在用户态启动高频并发线程,将共享内存中的长度数值在极小的合法数值与诸如 0x1000 这样的恶意超大数值之间来回切换。当内核调度刚好卡在两次读取的缝隙之间时,驱动就会按照小尺寸在内核分页池申请内存,却紧接着按照超大尺寸执行数据拷贝,瞬间触发分页池溢出。
更值得关注的是这处接口的触发条件。这处缺陷无法在系统全局环境中被任意未授权进程调用,受害者代码必须先利用特定的沙盒注册与配置机制,把自己主动标记为受隔离程序,置入 Avast 的自定义沙盒内部。这形成了一种奇特的因果倒置:原本用于压制未知恶意代码执行自由的隔离舱,反而成了能够合法向 aswSnx.sys 抛出特定 IOCTL 指令的唯一合法通道。
借道 I/O Ring:现代 Windows 11 下的提权跳跃
要将一处不可控的分页池越界写入转变为稳定的特权提升,在现代操作系统中绝非易事。微软早在 Windows 10 19H1 阶段就对分页池引入了段堆(Segment Heap)管理机制,由低碎片堆(LFH)和变长分配器(VS)协同工作,引入了高度随机化的槽位分配。
传统的覆盖函数指针或结构体头部的攻击手段在段堆机制面前往往直接导致系统崩溃蓝屏。攻击者在此次利用中选取的破局核心,是 Windows 11 引入的异步 I/O 新机制——I/O Ring。
虽然 _IORING_OBJECT 主结构被系统安置在非分页池,但其专门用来存放预先注册缓冲区的指针数组 RegBuffers,却刚好坐落在分页池。这个数组的大小完全取决于用户态注册了多少个缓冲区,每一个注册项占据 8 字节。这就给了攻击者量身定制内存尺寸的能力,使之能够通过精心构造的堆喷射,将 RegBuffers 数组精准安置在漏洞溢出点紧邻的内存槽位内。
当越界拷贝发生后,数组内的指针被改写,直接指向了攻击者在用户态预先伪造的缓冲区控制块结构。在缺乏内核级监督模式访问防范(SMAP)的环境下,驱动程序和内核在处理后续的异步读写任务时,会盲目解引用这个位于用户态的伪造对象:
- 调用
IoRingReadFile时系统从目标文件读取内容,并直接写入伪造指针指定的内核内存地址,完成任意内核写操作; - 调用
IoRingWriteFile时系统从伪造指针指定的内核地址读取数据并写入外部文件,由攻击者在用户态读取,完成任意内核读操作。
凭借这对读写原语,攻击链迅速穿透了多层限制。利用内核任意读取,程序顺藤摸瓜定位到自身的 _EPROCESS 结构体,随后修改其 Token 字段,将当前低权限身份神不知鬼不觉地替换为操作系统的最高权限 SYSTEM Token。最后,攻击链重新修复被破坏的内核池元数据以防止系统崩溃,整个过程没有引起任何常规防病毒监控的预警。
一座防线若要在内核建立威严,就绝不能把自身的特权接口当成未经验证的内庭通道。
杀软的结构性陷阱与底层访问改造
Avast 的这起危机再次将杀毒软件长期存在的结构性矛盾推向台前。为了监控进程行为,老牌杀毒软件倾向于在内核编写庞大的过滤驱动与沙盒逻辑,把大量本属于应用层的解析和参数分发直接放到了 ring 0 执行。这种架构虽然换来了对底层操作的强力掌控,但也把最高特权毫无遮拦地暴露给了可能被攻击的用户态输入。
作为对照,微软自带的 Windows Defender 近年采取了更偏向零信任的模块分离路线。Defender 倾向于在无特权的 AppContainer 沙箱内执行威胁样本的解析与扫描,特权动作则由独立的系统服务按需调度。尽管这种设计有效缩小了特权驱动的受攻击面,但近年来其特权更新与修复流程同样遭受过结构性冲击——例如代号为 BlueHammer(CVE-2026-33825)与 RoguePlanet(CVE-2026-50656)的漏洞事件,均证明了特权逻辑如果处理不当,隔离与修复流程本身也会被外部逆向利用。
为了从根本上遏制内核驱动屡屡栽倒在用户态内存访问上的顽疾,微软已经在推进所谓的 User-Mode Accessors(UMA)访问机制。传统的 ProbeForRead 仅能在某一瞬间确认用户内存有效,无法防止调用方随后偷偷改写值;而 UMA 则强制驱动通过带有 volatile 限定的专用 DDI 接口进行内存读取与安全拷贝,在拷贝落地到内核前阻断动态改写。然而这一底层防护并不能自动拯救所有第三方驱动,如果驱动开发者在完成安全读取后依然缺乏对数据上限和整数溢出的边界审查,内存破坏隐患依然会换个姿态再次登场。
针对受此漏洞影响的广大终端,安全防线的补强有着极其苛刻的操作门槛。本次漏洞全面覆盖低于 25.3 版本的 Avast Antivirus、AVG Antivirus 以及一体化套件 Avast One。
- 风险.日常的安全特征库与病毒定义更新对此类驱动层提权漏洞完全无效。系统管理员与终端用户必须将整个客户端套件升级至 25.3 或更高版本,并且必须完成完整的系统重启,确保旧版存在隐患的
aswSnx.sys内核驱动从系统内存中彻底卸载脱机。
