首页 > 代码库 > CVE-2010-0480分析 Microsoft MPEG Layer-3 - Stack Overflow
CVE-2010-0480分析 Microsoft MPEG Layer-3 - Stack Overflow
相关链接:https://www.exploit-db.com/exploits/14895/
环境介绍:XP Professional sp 3 Internet Explorer 6.0.2900.5512
漏洞描述:
https://technet.microsoft.com/zh-cn/library/security/ms10-026.aspx
根据官方描述,漏洞的成因是 Microsoft MPEG Layer-3 音频编码解码器不能正确处理包含 MPEG Layer-3 音频流的特制 AVI 文件。且是一个堆或栈溢出漏洞。
重现漏洞:
下载下载exploit-db链接中提供的压缩包,在xp虚拟机中解压并打开html文件,用windbg attach之后,允许运行ActiveX控件。
发生了异常,接下来收集信息,eip指向了一个错误的地址0x72000000,且函数调用堆栈已被破坏。观察栈上下的数据
根据 [esp-4] 的位置有错误的eip可以确定应该是一个栈溢出漏洞,也因为eip错误导致了访存异常。
用ub命令和dds esp找到距离异常流程最近的返回地址,定位到函数调用。可以看到两个l3codecx模块的地址,根据上面的漏洞描述可以知道漏洞发生在这个模块。
用IDA 打开l3codecx模块用于后续分析,发现没有符号能够加载。 ax是视频音频解码器的核心解码文件,文件里包涵了针对某个视频格式的解码函数,如果删除掉的话 自然对应的格式的视频音频文件将无法播放。
首先在IDA中定位第一个返回地址 0x72c4b14e
重新调试,并在 0x72C4B149 处下断,此时l3codecx模块还没加载。先用 sxe ld l3codecx 命令让调试器断在模块加载时,断下后再执行bp 0x72C4B149 运行。运行完后发现并没有发生异常。
为了定位漏洞只好不停的pct来跟踪到异常流程。
发现异常流程就在 0x72c4b15d 附近,重新调试断下后直接g运行,发现该处断点会断下两次,第二次才会发生异常。继续重新调试定位到第二次执行。跟进该函数继续pct。
继续跟进,整理一下流程
(1)sxe ld l3codecx 运行断下后下断
(2)bp 0x72c4b15d 运行到第二次
(3)bp 72c414ef
跟进后pct,发现就是这个 72c41ef0 函数内发生了栈溢出。
将72c41ef0这个函数标记为VulFunc后,重新调试,直接下断VulFunc的话 会断下两次,第二次会溢出,跟进第二次调用。用ba w4 esp来定位溢出栈的代码。
溢出的代码位置0x72c41ec5属于 sub_72C41DA0 函数 根据断下的指令虽然溢出了,但是是在将eax设置到缓冲区。该指令执行后将原来的返回地址清零成了0x72000000
执行前后对比:
sub_72C41DA0 函数大致分析如下,结合了IDA F5反编译代码。
unsigned int __stdcall sub_72C41DA0(void* arg_0, int arg_4, unsigned int arg_8) { DWORD v3,v4,v5,v6; switch(arg_8) { case 11025: v4 = 0; v3 = 52; v5 = 0; break; case 12000: v3 = 48; v4 = 0; v5 = 1024; break; case 16000: v3 = 36; v4 = 0x100000; v5 = 2048; break; case 22050: v3 = 26; v4 = 0x100000; v5 = 0; break; case 24000: v3 = 24; v4 = 0x100000; v5 = 1024; break; case 32000: v3 = 144; v4 = 1572864; v5 = 2048; break; case 44100: v3 = 104; v4 = 1572864; v5 = 0; break; case 48000: v3 = 96; v4 = 1572864; v5 = 1024; break; case 8000: v3 = 72; v4 = 0; v5 = 2048; break; default: v3 = arg_8; v4 = arg_8; v5 = arg_8; } //v3@esi v4@eax v5@ecx v6 = ( ( (arg_4 == 2 ? 0 : 3) | 0xFFFF8840 ) << 6 ) | v5 | v4; memset(arg_0,0,v3); *(_BYTE *)arg_0 = BYTE3(v6); *(_BYTE *)(arg_0 + 2) = BYTE1(v6); *(_BYTE *)(arg_0 + 1) = v6 >> 16; *(_BYTE *)(arg_0 + 3) = v6; *(_WORD *)(arg_0 + 4) = -13570; return v3; }
看着 0x72000000 就感觉像一个模块基址,就想起压缩包内有一个exploit.dll一开始以为是多余的,再用PEID工具查看这个exploit.dll的基址果然是0x72000000。
那么如何加载这个exploit.dll模块呢?继续看html文件,发现了一个特别的object标签。
可能是IE的版本太低了,换了03 Internet Explorer 6.0.3790.3959 就弹出了 提示加载exploit.dll的对话框。
但在XP上换了高版本IE 7也无法加载。。。也试了一些浏览器设置没找到原因,继续回去分析漏洞的成因。
memset函数 写入的地址为参数1,参数3可以控制写入的大小。
跟踪上层函数的调用,参数1来自一个局部变量v23。
对sub_72C41DA0函数下断重新调试,断下后。 参数3为0x93
根据IDA的分析,该局部变量位于偏移0x90处,所以0x93会溢出返回地址。
下载KB977816 补丁,打补丁前将l3codecx.ax 和 l3codecx.idb复制出来重命名为unpatch.ax 。打完补丁后对比文件版本信息。
定位到漏洞函数sub_72C41DA0,对两个idb文件进行比较。根据函数的偏移是在新模块中定位函数,对两个函数F5进行对比。
当没有匹配到值时,不再将参数3赋值给v3了,v3的默认值为0
CVE-2010-0480分析 Microsoft MPEG Layer-3 - Stack Overflow