CVE-2010-2553 Microsoft Windows Cinepak 編碼解碼器解壓縮漏洞 分析

Ox9A82發表於2016-07-28

     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

 

相關文章