CVE-2026-23673

admin 2026-09-06 04:37:21 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档分析CVE-2026-23673漏洞,源于REFS文件系统refscopywritea函数整数溢出导致越界读取。微软补丁增加参数验证,作者在Win10下通过挂钩refs.sys驱动内部函数实现内存补丁拦截,并讨论了驱动加载时机与挂钩方案。 综合评分: 85 文章分类: 漏洞分析,二进制安全,应急响应


CVE-2026-23673

原创

wowocock wowocock

无名小筑的奇妙旅程

2026年8月5日 18:15 北京

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

CVE-2026-23673

该漏洞源于ReFS文件系统RefsCopyWriteA函数整数溢出导致的越界读取。微软3月修了一个ReFS的越界读取漏洞,但因为WIN10没有更新,所以有必要在WIN10下做个内存补丁解决问题。

看了下微软做的补丁处理,原来是直接调用RefsCopyWriteInternal,补丁后加了参数验证。

看了下微软做的补丁处理,原来是直接调用RefsCopyWriteInternal,补丁后加了参数验证。

原版:

char __fastcall RefsCopyWriteA(

        struct _FILE_OBJECT *FileObject,

        union _LARGE_INTEGER *pOffset,

        __int64 Length,

        __int64 a4,

        int a5,

        void *a6,

        struct _IO_STATUS_BLOCK *IoStatus)

{

  union _LARGE_INTEGER v8[4]; // [rsp+40h] [rbp-38h] BYREF

  int v9; // [rsp+60h] [rbp-18h]

  int v10; // [rsp+64h] [rbp-14h]

  v8[0].QuadPart = 0i64;

  v8[1].QuadPart = 0i64;

  v8[3].QuadPart = 0i64;

  v10 = 0;

  if ( !a6 )

    return 0;

  v8[2] = *pOffset;

  v9 = Length;

  return RefsCopyWriteInternal(FileObject, v8, a4, a5, a6, 0i64, IoStatus);

}

补丁版

char __fastcall RefsCopyWriteA(

        __int64 FileObject,

        __int64 *pOffset,

        unsigned int Length,

        unsigned __int8 a4,

        unsigned int a5,

        __int64 Buffer,

        __int64 IoStatus)

{

  __int64 StartOffset; // rdx

  __int64 v9[2]; // [rsp+40h] [rbp-38h] BYREF

  unsigned int len; // [rsp+50h] [rbp-28h]

  __int128 v11; // [rsp+54h] [rbp-24h]

  int v12; // [rsp+64h] [rbp-14h]

  v12 = 0;

  v11 = 0i64;

  if ( Buffer

    && ((StartOffset = *pOffset, v9[0] = StartOffset, v9[1] = StartOffset + Length, len = Length, StartOffset < 0)// StartOffset(v9[0]) EndOffset(v9[1])

     || StartOffset <= StartOffset + Length) )

  {

    return RefsCopyWriteInternal(FileObject, v9, a4, a5, Buffer, 0i64, IoStatus);

  }

  else

  {

    return 0;

  }

}

发生奔溃的时候

 start: 7fffffff`fffffff0

end:      80000000`000001f0

虽然看起来end比start大,但因为是有符号数比较,所以变成了end 比start 小,所以补丁后跳到了直接返回FALSE,从而绕过了后续调用,所以如果我们要做补丁,也应该用类似的操作,但需要找到如何打内存补丁的位置,需要好好研究下。

PAGE:00000001402FC96C                 jnz     short loc_1402FC973

PAGE:00000001402FC96E                 cmp     rdx, rcx

PAGE:00000001402FC971                 jg      short loc_1402FC9AA

PAGE:00000001402FC973

PAGE:00000001402FC973 loc_1402FC973:                          ; CODE XREF: RefsCopyWriteA+4C↑j

PAGE:00000001402FC973                 mov     rax, [rsp+78h+IoStatus]

PAGE:00000001402FC97B                 lea     rdx, [rsp+78h+var_38]

PAGE:00000001402FC980                 mov     [rsp+78h+var_48], rax

PAGE:00000001402FC985                 movzx   r8d, r11b

PAGE:00000001402FC989                 mov     [rsp+78h+var_50], r9

PAGE:00000001402FC98E                 mov     rcx, rbx

PAGE:00000001402FC991                 mov     r9d, [rsp+78h+arg_20]

PAGE:00000001402FC999                 mov     [rsp+78h+var_58], r10

PAGE:00000001402FC99E                 call    RefsCopyWriteInternal

PAGE:00000001402FC9A3                 add     rsp, 70h

PAGE:00000001402FC9A7                 pop     rbx

PAGE:00000001402FC9A8                 retn

PAGE:00000001402FC9A8 ; —————————————————————————

PAGE:00000001402FC9A9                 align 2

PAGE:00000001402FC9AA

PAGE:00000001402FC9AA loc_1402FC9AA:                          ; CODE XREF: RefsCopyWriteA+29↑j

PAGE:00000001402FC9AA                                         ; RefsCopyWriteA+51↑j

PAGE:00000001402FC9AA                 xor     al, al

PAGE:00000001402FC9AC                 add     rsp, 70h

PAGE:00000001402FC9B0                 pop     rbx

PAGE:00000001402FC9B1                 retn

在装了火绒的WIN10X64 22H2机器上复现了问题,可见DUMP的调用栈里并没有我们的minifilter,其是直接通过FASTIO接口走缓存接口,没有走文件接口,所以无法在minifilter里进行拦截。

CUSTOMER_CRASH_COUNT:  1

PROCESS_NAME:  CVE-2026-23673_ReFS_PoC.exe

STACK_TEXT:

fffffe80ad7091e8 fffff8013146cb2e : 0000000000000034 000000000000056c ffffffffc0000420 0000000000000000 : nt!KeBugCheckEx

fffffe80ad7091f0 fffff801312cf5f8 : ffffc88400000000 0000000000000000 fffffe80ad709300 fffffe80ad7092e4 : nt!CcGetVirtualAddress+0x1ae58e

fffffe80ad709290 fffff80131248a0a : ffffc88482cc1530 00000270f1ccd030 fffffe80ad709488 fffff80100001000 : nt!CcMapAndCopyInToCache+0x2f8

fffffe80ad709430 fffff80131506f69 : ffffc88481ac62a8 fffff801312e6350 ffffc88400000002 ffffa78000000000 : nt!CcCopyWriteEx+0xea

fffffe80ad7094b0 fffff80148d8e768 : ffffa780fb647c60 ffffc88400000002 ffffa78000000000 0000000000000000 : nt!CcCopyWrite+0x19

fffffe80ad7094f0 fffff80148d8e257 : ffffc8848352aa20 ffffc88481c91010 0000000000000000 fffff80148cfe540 : ReFS!RefsCopyWriteInternal+0x504

fffffe80ad709700 fffff80130ec783c : 0000000000000000 fffffe80ad709868 fffffe80ad709828 00000270f1ccd030 : ReFS!RefsCopyWriteA+0x67

fffffe80ad709780 fffff80130ec464a : fffffe80ad709890 fffffe80ad709828 ffffc88481697110 ffffc88481697010 : FLTMGR!FltpPerformFastIoCall+0x16c

fffffe80ad7097e0 fffff80130ef9525 : fffffe80ad70a000 fffffe80ad704000 ffffc88400000008 ffffc88483426d60 : FLTMGR!FltpPassThroughFastIo+0x10a

fffffe80ad709860 fffff801315ebcaf : fffffe80ad709901 ffffc8847c7a0080 0000000000000000 ffffc8847c7a0080 : FLTMGR!FltpFastIoWrite+0x165

fffffe80ad709910 fffff801316e62b0 : ffffc88483426ef0 0000000000000000 0000000000000000 0000000000000000 : nt!IopWriteFile+0x137

fffffe80ad709a10 fffff8013142e505 : fffffe80ad709b80 000000ac1eeffcc8 0000000000000000 000000ac1eeff638 : nt!NtWriteFile+0xd0

fffffe80ad709a90 00007ffcf7dad6a4 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : nt!KiSystemServiceCopyEnd+0x25

000000ac1eeffca8 0000000000000000 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : 0x00007ffc`f7dad6a4

SYMBOL_NAME:  ReFS!RefsCopyWriteInternal+504

MODULE_NAME: ReFS

IMAGE_NAME:  ReFS.SYS

IMAGE_VERSION:  10.0.19041.6456

STACK_COMMAND:  .thread ; .cxr ; kb

BUCKET_ID_FUNC_OFFSET:  504

FAILURE_BUCKET_ID:  0x34_ReFS!RefsCopyWriteInternal

OS_VERSION:  10.0.19041.1

BUILDLAB_STR:  vb_release

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 10

FAILURE_ID_HASH:  {5724ddfb-0dc9-f924-7ab4-3cd3f030ef81}

Followup:     MachineOwner

所以只能考虑挂钩refs.sys驱动内部的RefsCopyWriteA来进行拦截,微软的补丁也是修改了这个函数增加了验证。

从Win 10开始,微软推出了ReFS文件系统,也叫做“弹性文件系统”其也是类似于NFS的文件系统所以遵循常规文件系统驱动的开发规律,其内部也提供了常规的irp操作和fastio操作,所以我们可以找到refs文件系统的驱动对象,然后找到其对应的fastio函数指针地址,挂钩里面的指针,采用类似IRP HOOK的方式挂钩fastio操作,从而可以直接挂钩RefsCopyWriteA,这种方式是通用性最好,而且因为是指针替换应该也不会触发PG。

默认情况下的Windows 10不能直接创建refs格式的磁盘,需要开启开发者模式创建dev drive。所以驱动可能会动态加载,所以可能要考虑2种情况

1,我们驱动加载的时候,refs驱动已经加载了,我们可以直接挂钩该驱动进行拦截处理

2,我们驱动加载的时候,可能该驱动还没加载,所以需要注册一个模块回调,在模块回调里检测refs驱动的加载,然后进行HOOK处理。

而挂钩后的处理,很简单,只要照搬微软的方式,进行

相应的参数验证即可。

由于MINIFILTER无法处理fastio操作,也可以考虑采用传统框架的 sfilter来处理。

实际需要编写代码验证。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。

本文转载自:无名小筑的奇妙旅程 wowocock wowocock《CVE-2026-23673》

CVE-2026-23673 网络安全文章

CVE-2026-23673

文章总结: 该文档分析CVE-2026-23673漏洞,源于REFS文件系统refscopywritea函数整数溢出导致越界读取。微软补丁增加参数验证,作者在W
关于容器逃逸攻击的内训 网络安全文章

关于容器逃逸攻击的内训

文章总结: 本文系统梳理云上容器逃逸攻击全流程方法论,涵盖基础设施背景、攻击目标范围、标准原则、准备工作等维度。指出94%企业生产环境运行容器化应用但近60%集
评论:0   参与:  0