首页 > 代码库 > 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;
}
View Code

   看着 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