CVE-2012-0003 MIDI 文件堆溢出分析

Author Avatar
kabeor 12月 31, 2019

CVE-2012-0003 MIDI 文件堆溢出分析

该漏洞成因主要是由于 winmm.dll 动态链接库在处理 MIDI 文件的 Note On 和 Note Off 字段没有做限制,导致可以操纵该字段访问堆块之外 1 个字节的内存空间;由于该漏洞过于特殊,所以在分析和利用的时候难度是相当大的。

分析环境

Windows XP SP3 x86
Windbg 6.12.2.633
IE6 wnimm.dll

MIDI 文件格式

MIDI 全称 Musical Instrument Digital Interface,是一种乐器数字接口(通过winmm.dll 链接库解析这种格式的文件之后可以播放出音乐)

总体来说 MIDI 可分为 “头块” 和若干多的 “音轨块”

头块结构如下

音轨事件如下

分析过程

漏洞定位

poc.html 样本中嵌入了一个音频播放器,由音频播放器来调用 toto.mid 文件播放音频从而触发漏洞

如果先运行windbg设置堆溢出检测标志,当前IE进程将无法运行poc,需要在命令行先设置gflag再运行windbg。

F5 运行之后将 poc.html 文件拖入 IE,并且允许运行 ActiveX 控件
断下异常,可以看出 esi 指向的地址超出了堆空间,之后被堆页保护捕捉到

漏洞分析

shift + F4 对 v2、v9、v11、v13、v21、v23 和 v20 下条件记录断点,记录表达数值
v20 int3断点
运行poc后查看日志

分析看出 v11、v13、v21 相等
v2 不变,v20 最后才被记录,且指向的地址都在 0x07EC0000 往后的堆中
v23 的值,也就是 0x007DB29F 是来自漏洞样本的数据,结合MIDI 格式分析可以知道,9F 代表的就是打开音符(Note On),F 就是通道号

通道号 F 经过计算之后值为 419,控制着指针的偏移地址,也就是 v24 的值
v20 由传入的参数 wParam 控制,midiOutTimerTick函数调用了 midiOutPlayNextPolyEvent 函数,并且把 v6 当作参数传入,而 v6 = gpEmuList,gpEmuList在mseOpen 函数中被引用

最后分析出v20=v6,因为 v6 是堆块的基地址,且这个堆块的大小为 0x400,所以 v20 也为这个 0x400 堆块的基地址

v25 的指针由 v24 和 v20 相加得出,v20 是堆的基址,而 v24 是样本数据解析运算获得,由于没有限制通道号的大小,导致运算后的偏移地址 v24 为 419,可是堆只有 0x400大小,很显然超出了申请的堆空间,照成了非法访问,故引发了堆页保护异常

From https://kabeor.github.io/CVE-2012-0003 MIDI 文件堆溢出分析/ bye

This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接:https://kabeor.github.io/CVE-2012-0003 MIDI 文件堆溢出分析/