CVE-2010-2553 Microsoft Windows Cinepak 编码解码器解压缩漏洞 分析

     Microsoft Windows是微软发布的非常流行的操作系统。
        Microsoft Windows XP SP2和SP3,Windows Vista SP1和SP2,以及Windows 7中的Cinepak 编码解码器处理受支持格式文件的方式中存在一个远程执行代码漏洞。 如果用户打开特制的媒体文件,此漏洞可能允许执行代码。 如果用户使用管理用户权限登录,成功利用此漏洞的攻击者便可完全控制受影响的系统。 攻击者可随后安装程序;查看、更改或删除数据;或者创建拥有完全用户权限的新帐户。 那些帐户被配置为拥有较少系统用户权限的用户比具有管理用户权限的用户受到的影响要小。

     我们已知这是一个堆漏洞了,那么肯定少不了去加上hpa和ust调试支持以便于第一时间的获取崩溃信息。加载poc,崩溃信息如下:

(4a8.b8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00006000 ebx=0e0defc0 ecx=00000800 edx=0e6afd38 esi=0e4c1000 edi=0e4c3000
eip=73b722cc esp=0e6afd04 ebp=0e6afd30 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
iccvid!CVDecompress+0x11e:
73b722cc f3a5            rep movs dword ptr es:[edi],dword ptr [esi] es:0023:0e4c3000=???????? ds:0023:0e4c1000=80109012

目测是往堆里复制溢出了引发的异常。我们看下edi=0e4c3000到底是不是堆,!heap -p -a 0e4c3000 输出如下,看来真的是堆,符合我们的推测

0:028> ?edi
Evaluate expression: 239874048 = 0e4c3000
0:028> !heap -p -a 0e4c3000
    address 0e4c3000 found in
    _DPH_HEAP_ROOT @ a1000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                 e128c30:          e4bd000             6000 -          e4bc000             8000
    7c938f01 ntdll!RtlAllocateHeap+0x00000e64
    7c809a7f kernel32!LocalAlloc+0x00000058
    73b724a8 iccvid!CVDecompressBegin+0x00000080
    73b7c6a0 iccvid!DecompressBegin+0x00000214
    73b766a1 iccvid!DriverProc+0x00000198
    73b41938 MSVFW32!ICSendMessage+0x0000002b
    7cf8df11 quartz!CAVIDec::StartStreaming+0x00000278
    7cfbfa7a quartz!CVideoTransformFilter::Receive+0x000000cf
    7cf90929 quartz!CTransformInputPin::Receive+0x00000033
    7cf8e672 quartz!CBaseOutputPin::Deliver+0x00000022
    7cf90c90 quartz!CBaseMSRWorker::TryDeliverSample+0x00000102
    7cf90e0c quartz!CBaseMSRWorker::PushLoop+0x0000015e
    7cf8ce28 quartz!CBaseMSRWorker::DoRunLoop+0x0000004a
    7cf8dbde quartz!CBaseMSRWorker::ThreadProc+0x00000039
    7c80b729 kernel32!BaseThreadStart+0x00000037

我们这里简单的算一个数学问题e4bd000+6000=E4C3000,而异常时正断在E4C3000这也是页堆的功劳,不了解页堆的可以看我前面写的博文或者《软件调试》。我们再来看看ecx的值

0:028> ? ecx
Evaluate expression: 2048 = 00000800

很明显这个ecx是小于堆的0x6000个字节的。我们对73b722cc下断,来看看到底谁造成的溢出。我们重新断下结果如下,可以看出ecx=800,而edi=0f488000,我们知道堆底在f486000+6000=F48C000明显没有溢出。我们推测是经过了多次复制才导致了溢出,对这个复制语句上方下条件记录断点,如图

'条件记录断点:'
edi=0e4cb000
ecx=00000800
'条件记录断点:'
edi=0e4cd000
ecx=00000800
'条件记录断点:'
edi=0e4cf000
ecx=00000800

我们看最后的一次edi+ecx*4=0xe4cf00+0x800*4=E4EF00所以是大于,堆底的0xE4C3000+0x6000=E4CF000。就是说可以容纳0x6000个字节,但是从0x2000的位置向堆中写那么就会有0x2000个字节的溢出了。下三次条件断点,查看栈回溯即可得到如下的结果,可见这三次的栈回溯都是完全一致的,据此我们可以找到调用的位置。

0:000> bu iccvid!CVDecompress+0x118 ".echo 条件记录断点:;r edi;r ecx"
0:000> g
条件记录断点:
edi=0f157000
ecx=00000800
eax=00002000 ebx=0f170fc0 ecx=00000800 edx=0f4cfd38 esi=0efd0b12 edi=0f157000
eip=73b722c6 esp=0f4cfd04 ebp=0f4cfd30 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
iccvid!CVDecompress+0x118:
73b722c6 8db700e0ffff    lea     esi,[edi-2000h]
0:029> kp
ChildEBP RetAddr  
0f4cfd30 73b7cbf3 iccvid!CVDecompress+0x118
0f4cfd60 73b766c8 iccvid!Decompress+0x11d
0f4cfdac 73b41938 iccvid!DriverProc+0x1bf
0f4cfdd0 7cf8fa8e MSVFW32!ICSendMessage+0x2b
0f4cfe00 7cf8f9d9 quartz!CVFWDynLink::ICDecompress+0x3e
0f4cfec0 7cf90a45 quartz!CAVIDec::Transform+0x282
0f4cfeec 7cf90929 quartz!CVideoTransformFilter::Receive+0x110
0f4cff00 7cf8e672 quartz!CTransformInputPin::Receive+0x33
0f4cff10 7cf90c90 quartz!CBaseOutputPin::Deliver+0x22
0f4cff40 7cf90e0c quartz!CBaseMSRWorker::TryDeliverSample+0x102
0f4cff84 7cf8ce28 quartz!CBaseMSRWorker::PushLoop+0x15e
0f4cff9c 7cf8dbde quartz!CBaseMSRWorker::DoRunLoop+0x4a
0f4cffa4 7cf8a12f quartz!CBaseMSRWorker::ThreadProc+0x39
0f4cffb4 7c80b729 quartz!CAMThread::InitialThreadProc+0x15
0f4cffec 00000000 kernel32!BaseThreadStart+0x37
0:029> g
条件记录断点:
edi=0f159000
ecx=00000800
eax=00004000 ebx=0f170fc0 ecx=00000800 edx=0f4cfd38 esi=0efd0b22 edi=0f159000
eip=73b722c6 esp=0f4cfd04 ebp=0f4cfd30 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
iccvid!CVDecompress+0x118:
73b722c6 8db700e0ffff    lea     esi,[edi-2000h]
0:029> kp
ChildEBP RetAddr  
0f4cfd30 73b7cbf3 iccvid!CVDecompress+0x118
0f4cfd60 73b766c8 iccvid!Decompress+0x11d
0f4cfdac 73b41938 iccvid!DriverProc+0x1bf
0f4cfdd0 7cf8fa8e MSVFW32!ICSendMessage+0x2b
0f4cfe00 7cf8f9d9 quartz!CVFWDynLink::ICDecompress+0x3e
0f4cfec0 7cf90a45 quartz!CAVIDec::Transform+0x282
0f4cfeec 7cf90929 quartz!CVideoTransformFilter::Receive+0x110
0f4cff00 7cf8e672 quartz!CTransformInputPin::Receive+0x33
0f4cff10 7cf90c90 quartz!CBaseOutputPin::Deliver+0x22
0f4cff40 7cf90e0c quartz!CBaseMSRWorker::TryDeliverSample+0x102
0f4cff84 7cf8ce28 quartz!CBaseMSRWorker::PushLoop+0x15e
0f4cff9c 7cf8dbde quartz!CBaseMSRWorker::DoRunLoop+0x4a
0f4cffa4 7cf8a12f quartz!CBaseMSRWorker::ThreadProc+0x39
0f4cffb4 7c80b729 quartz!CAMThread::InitialThreadProc+0x15
0f4cffec 00000000 kernel32!BaseThreadStart+0x37
0:029> g
条件记录断点:
edi=0f15b000
ecx=00000800
eax=00006000 ebx=0f170fc0 ecx=00000800 edx=0f4cfd38 esi=0efd0b32 edi=0f15b000
eip=73b722c6 esp=0f4cfd04 ebp=0f4cfd30 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
iccvid!CVDecompress+0x118:
73b722c6 8db700e0ffff    lea     esi,[edi-2000h]
0:029> kp
ChildEBP RetAddr  
0f4cfd30 73b7cbf3 iccvid!CVDecompress+0x118
0f4cfd60 73b766c8 iccvid!Decompress+0x11d
0f4cfdac 73b41938 iccvid!DriverProc+0x1bf
0f4cfdd0 7cf8fa8e MSVFW32!ICSendMessage+0x2b
0f4cfe00 7cf8f9d9 quartz!CVFWDynLink::ICDecompress+0x3e
0f4cfec0 7cf90a45 quartz!CAVIDec::Transform+0x282
0f4cfeec 7cf90929 quartz!CVideoTransformFilter::Receive+0x110
0f4cff00 7cf8e672 quartz!CTransformInputPin::Receive+0x33
0f4cff10 7cf90c90 quartz!CBaseOutputPin::Deliver+0x22
0f4cff40 7cf90e0c quartz!CBaseMSRWorker::TryDeliverSample+0x102
0f4cff84 7cf8ce28 quartz!CBaseMSRWorker::PushLoop+0x15e
0f4cff9c 7cf8dbde quartz!CBaseMSRWorker::DoRunLoop+0x4a
0f4cffa4 7cf8a12f quartz!CBaseMSRWorker::ThreadProc+0x39
0f4cffb4 7c80b729 quartz!CAMThread::InitialThreadProc+0x15
0f4cffec 00000000 kernel32!BaseThreadStart+0x37

 我们对此调用及上层调用进行分析,如下所示:

.text:73B722BB                 mov     ecx, [ebx+1Ch]
.text:73B722BE                 lea     edi, [ecx+eax]
.text:73B722C1                 mov     ecx, 800h
.text:73B722C6                 lea     esi, [edi-2000h]
.text:73B722CC                 rep movsd
.text:73B7CBD8                 push    dword ptr [esi+98h]
.text:73B7CBDE                 push    edi
.text:73B7CBDF                 push    [ebp+arg_20]
.text:73B7CBE2                 push    [ebp+arg_24]
.text:73B7CBE5                 push    [ebp+arg_28]
.text:73B7CBE8                 push    [ebp+arg_C]
.text:73B7CBEB                 push    dword ptr [esi+5Ch]
.text:73B7CBEE                 call    sub_73B721AE
原文地址:https://www.cnblogs.com/Ox9A82/p/5715673.html