Windows图形漏洞深度分析:远程代码执行与内存泄露

本文详细分析了Windows图形设备接口(GDI)中的三个安全漏洞,包括CVE-2025-30388、CVE-2025-53766和CVE-2025-47984,这些漏洞可导致远程代码执行和内存泄露,涵盖了漏洞的技术细节、利用方式和修复方案。

背景

Check Point Research (CPR) 在Windows图形设备接口(GDI)中发现了三个安全漏洞。我们及时向微软报告了这些问题,并在2025年5月、7月和8月的补丁星期二更新中得到了解决。

这些漏洞包括:

  • CVE-2025-30388,评级为重要,被认为更有可能被利用;
  • CVE-2025-53766,分类为严重级别,可能允许远程攻击者在受影响的系统上执行任意代码;
  • CVE-2025-47984,同样评级为重要,可能导致通过网络未经授权披露敏感信息。

几何图形失控 - CVE-2025-30388

我们发现了与处理EmfPlusDrawStringEmfPlusFillRectsEmfPlusFillClosedCurve记录相关的三个独立崩溃。所有三种情况都有一个共同的根本原因:另一个记录为利用设置了条件。

GdiPlus.dll模块的10.0.26100.3037版本中,ScanOperation::AlphaMultiply_sRGB()ScanOperation::Blend_sRGB_sRGB_MMX()EpAntialiasedFiller::OutputSpan()函数中发生了多次访问违规异常。

此漏洞可能允许远程攻击者使用特制的EMF+元文件执行越界读取或写入内存操作。

在我们的崩溃样本中,EmfPlusClear记录位于元文件中的EmfPlusDrawString记录之前。该记录清除输出坐标空间并使用背景颜色和透明度进行初始化,如其Color字段所定义。该字段包含一个指定红、绿、蓝和alpha分量的EmfPlusARGB对象。

进一步调查显示,EmfPlusClear记录处理程序使用EpScanBitmap::Start()函数分配一个堆块来存储4000字节(0xFA0)。然后在处理EmfPlusDrawString记录期间,使用指定的EmfPlusARGB对象填充此缓冲区,该对象经过AlphaMultiply_sRGB()函数的alpha乘法处理。

存储在ebx寄存器中的循环计数器从0x950开始。由于每次迭代将4字节对象写入ecx + edx处的目标缓冲区,当计数器达到0x567时,函数在1000字节后越界写入。

负空间 - CVE-2025-53766

我们在处理EmfPlusDrawRects记录时发现了第四次崩溃。在GdiPlus.dll的10.0.26100.4202版本中,ScanOperation::AlphaDivide_sRGB()函数尝试写入保留但未分配的内存时发生了访问违规异常。

此漏洞可能允许远程攻击者使用特制的EMF+元文件执行越界内存写入。

此问题与我们之前讨论的CVE-2025-30388漏洞类似。该漏洞是由EmfPlusSetTSClip记录中的无效RECT对象引起的,该记录位于发生崩溃的其他记录之前。在这个新案例中,漏洞源于受影响EmfPlusDrawRects记录中的一系列EmfPlusRect对象。

EmfPlusDrawRects记录前面有一个EmfPlusObject记录,该记录指定了在图形操作中使用的EmfPlusPen对象。EmfPlusPen对象定义了与笔关联的图形画刷。该画刷是一个纯色画刷,由EmfPlusARGB值表征。

进一步分析显示,EpScanBitmap::NextBuffer()函数从未验证要处理的扫描线数量是否适合目标位图,这意味着如果调用请求的扫描线多于存在的扫描线,该函数可能会被诱骗读取或写入图像底部边缘之外。

未完成的事务 - CVE-2025-48984

我们在处理EMR_STARTDOC记录时发现了第五次崩溃,这立即显现出与CVE-2022-35837漏洞相关。在gdi32full.dll的10.0.26100.3624版本中,StringLengthWorkerW()函数尝试读取288/0x120字节堆块末尾的内存时发生了访问违规异常。

堆栈跟踪表明问题可能在于StringLengthWorkerW()函数,该函数对用户控制的数据执行长度检查,并假定输入是以空字符结尾的字符串。但是,如果提供的字符串不是以空字符结尾,该函数可能会读取超出分配缓冲区的范围,导致潜在的信息泄露。

越界读取的发生是因为MRSTARTDOC::bPlay()函数验证记录内的字符串偏移量。特制的元文件可能会填充lpszDocName字段中的第一个字符串,使其几乎到达记录的末尾。复制该字符串后,代码将其内部游标推进到该点之后,但对lpszOutput字段的下一个验证仍然将提供的偏移量视为相对于记录的原始基址。

这种差异允许攻击者提供一个通过MR::bValidOff()函数检查但实际上指向堆块外部的值。由于找不到空终止符,StringLengthWorkerW()函数继续读取相邻内存,暴露其内容。

结论

我们在Windows GDI中发现的漏洞可能对系统安全产生严重影响。我们对EMF+文件的广泛调查表明,要领先于潜在威胁需要持续的关注和适应。

安全漏洞可能会持续多年未被发现,通常由于不完整的修复而重新出现。特定的信息泄露漏洞,尽管通过安全补丁正式解决,但由于原始问题仅得到部分修复,多年来仍然活跃。这个例子突显了研究人员面临的基本难题:引入漏洞通常很容易,修复它可能很困难,而验证修复是否彻底有效则更具挑战性。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计