CVE-2010-3974 Investigation

7erry

Microsoft Windows Cover Page 在 Windows 中主要用于个性化传真及呈现更正式外观的传真传输,当使用 Microsoft Windows Fax Cover Page Editor 打开特制的 .cov 传真封面文件时,会因为解析错误导致 double free 漏洞,进而允许任意代码执行。

影响范围:

Microsoft Windows Server 2003 SP2
Microsoft Windows Server 2008 Gold, SP2, R2, R2 SP1
Microsoft Windows XP SP2, SP3
Microsoft Windows Vista SP1 and SP2
Microsoft Windows 7 Gold, SP1

漏洞分析

开启 ust 和 hfc,调试运行 fxscover.exe 并打开样本后程序因触发 Break Instruction 异常而崩溃。崩溃位置位于 ntdll!RtlReportCriticalFailure,显然这不是问题发生的第一现场。栈回溯得到函数调用关系

1
2
3
4
5
6
7
8
9
FXSCOVER!CDrawDoc::DeleteContents+0xc
-> FXSCOVER!CDrawDoc::Remove+0x96
-> FXSCOVER!CDrawRoundRect::`scalar deleting destructor'
-> msvcrt!free+0xcd
-> ntdll!RtlFreeHeap+0x142
-> ntdll!RtlpFreeHeap
-> ntdll!RtlpAnalyzeHeapFailure
-> ntdll!RtlpLogHeapFailure
-> ntdll!RtlReportCriticalFailure

参考漏洞描述,或者说由于已知漏洞的成因是 double free,可以先在 msvcrt!free 函数处下一个条件断点,随后再次打开样本使程序崩溃。查看条件断点的输出历史,发现崩溃前最后一次 free 时的 esi 寄存器值出现了两次。当然更直接的验证程序漏洞成因的方法是在 msvcrt!free 函数及其主调函数处下断点,随后跟进执行至 msvcrt!free 函数并通过 !heap -p -a 指令查看此时的 esi 所指向的堆块。其结果符合预期,state 为 free。

由于 msvcrt!free 函数的主调函数是一个对象的析构方法,IDA 里找虚函数找的我有点头大,该漏洞的分析方法就参照《漏洞战争》一书进行补丁分析而非直接逆向分析的方式定位漏洞成因。事实上通过补丁分析漏洞是实际的漏洞分析手段中最实用的方法。

下载 Windows 7 MS11-024 补丁并使用 IDA 和 BinDiff 进行补丁比较,发现只有三个函数发生了修改。分别是 CDrawPoly::Serialize(CArchive &), CDrawDoc::Serialize(CArchive &)CDrawText::GetText(int, int)。参照之前的分析结果,看向 CDrawDoc::Serialize(CArchive &) 函数,发现该函数 patch 后新增了一段代码,其反编译结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while ( 1 )
{
v6 = v9[0];
if ( !v9[0] )
break;
v8 = 0;
v7 = *CPtrList::GetNext((CDrawDoc *)((char *)this + 160), v9);
if ( v7 )
{
v11 = CDrawDoc::IsObjectAlreadySerialized(this, v7, v11, &v8);
if ( !v8 )
continue;
}
CObList::RemoveAt((CDrawDoc *)((char *)this + 160), v6);
}
postorder_deletion(v11);

这段代码会遍历 CPtrList 中的 CDrawDoc 对象指针,判断其指向对象是否被序列化,如果未被序列化,就从列表中移除索引到的对象。因此推测 unpatched fxscover.exe 的漏洞成因为 CPtrList 中存在未被序列化的 CDrawDoc 对象指针,且该对象指针指向了一块已被 free 的内存区域,导致它在后续执行流程中被移除时造成 double free

当然也可能是检测索引到的对象指针,若其指向的目标已经被序列化则移除,未序列化则保留。这种情况下序列化后的对象将会被 free,因此未被移除的已被序列化的对象在后续执行流程中再次被序列化造成 double free

漏洞利用

MSF 中未搜索到该漏洞的 exp,按照《漏洞战争》的说法其 exp 被公布并收录在了 exploit-db 上,可惜我去查阅的时候发现它已经被删除了。不过根据分析结果来看,这个漏洞为攻击者提供的可操作空间是比较大的,例如程序在调用 MFC42u!CObject::IsKindOf 函数时会引用已释放的内存,并取其对应的内存值作为虚表指针索引并调用虚函数。故该漏洞完全可以用于堆喷,并在拿到虚函数表基址时用于劫持控制流,跳转到 ROP 链或 shellcode。应该是比较典型的该类型漏洞利用方式,在此不再赘述

漏洞修复

如漏洞分析部分所言,补丁添加了一段根据索引目标指向对象序列化与否移除 CDrawDoc 对象指针的代码修复了该漏洞

Reference

Github - CVE-2010-3974
Microsoft 安全公告 MS11-024 - 重要
NVD - CVE-2010-3974
CVE - CVE-2010-3974
漏洞战争

  • Título: CVE-2010-3974 Investigation
  • Autor: 7erry
  • Creado el : 2025-02-02 18:53:57
  • Actualizado el : 2025-02-02 18:53:57
  • Enlace: https://7erryx.github.io/2025/02/02/Vulnerability Investigation/CVE-2010-3974-Investigation/
  • Licencia: Este trabajo está licenciado bajo CC BY-NC-SA 4.0.
Comentarios
En esta página
CVE-2010-3974 Investigation