0x01 蜘蛛漏洞攻击包

  • 前言:2012 年 2月,地下黑产中流行着一款国产名为蜘蛛漏洞的攻击包 —— “Zhi-Zhu Exploit Pack”,该工具包含 5 个漏洞,都是在当时比较流行的漏洞,涵盖了 Flash、IE 等产品,其中就包含 CVE-2012-0003,此国产漏洞利用包与国外有一定的差别;国外通常用于构建僵尸网络或者窃取重要的情报,而 “蜘蛛” 这款漏洞攻击包主要用于盗取游戏账号,比如 “龙之谷”,这似乎也比较复合国情
  • 微软发布该漏洞补丁之后,国外安全团队 VUPEN 在其博客上公布了该漏洞的成因和利用方法,其中对漏洞的利用构造的相当精妙,堪称艺术,可谓经典中的经典
  • 该漏洞成因主要是由于 winmm.dll 动态链接库在处理 MIDI 文件的 Note On 和 Note Off 字段没有做限制,导致可以操纵该字段访问堆块之外 1 个字节的内存空间;由于该漏洞过于特殊,所以在分析和利用的时候难度是相当大的

0x02 分析环境

  • 虚拟机:Windows XP sp3,版本:11.0.8211(提取码:woi9)、Sublime Text3
  • 调试工具:Windbg(Windbg32Windbg64)、ODIDA(提取码:v0pt)、C32Asm(16进制分析文件工具,提取码:4sj8)
  • 漏洞程序:IE6 浏览器
  • 漏洞DLL:有漏洞的 winmm.dll 动态链接库文件(提取码:0n2a)
  • 漏洞样本:能够触发漏洞 POC 样本(包含 poc.html 和 toto.mid 两个文件,提取码:nd0b)

0x03 MIDI 文件格式

  • 想要理解漏洞的成因,首先需要了解什么是 MIDI 文件格式:MIDI 全称 Musical Instrument Digital Interface,是一种乐器数字接口,说白了就是一种音频格式(通过winmm.dll 链接库解析这种格式的文件之后可以播放出音乐)
  • 总体来说 MIDI 可分为 “头块” 和若干多的 “音轨块”
块名称 块标记(4个字节) 块长度(4个字节) 块数据
头块 "MThd" 00 00 00 06 6个字节长度
音轨块1 "MTrk" 后面块数据长度 音轨事件数据,按时间顺序排序
音轨块2 "MTrk" 后面块数据长度 音轨事件数据,按时间顺序排序
... ... ... ...
音轨块n "MTrk" 后面块数据长度 音轨事件数据,按时间顺序排序
  • 头块结构如下
偏移 长度 描述 数值
0x00 4 块标记 "MThd"
0x04 4 块长度 00 00 00 06
0x08 2 格式类型 0 ~ 2
0x10 2 音轨数 1 ~ 65535
0x12 2 时间计数值(每拍的计数值) 比如数值 0x60 就为八分一拍
  • 音轨事件如下

注意:这个是音轨事件,不是音轨的结构,一个音轨结构中可以包含许多的音轨事件

事件类型 格式 描述
关闭音符(Note Off) 0x8n note velocity n 代表通道号,note 代表高音数值,velocity 代表按键速度
打开音符(Note On) 0x9n note velocity n 代表通道号,note 代表高音数值,velocity 代表按键速度
触后音符(Note Aftertouch) 0xAn note amount n 代表通道号,note 代表高音数值,amount 代表按压力度
控制器(Controler) 0xBn type value n 代表通道号,note 代表控制项(如主音、延音等音量大小的调节),value 即为设置值
音色切换(Program Change) 0xCn num n 代表通道号,num 代表音色号
触后通道(Channel Afertouch) 0xCn note amount n 代表通道号,note 代表高音数值,amount 代表按压力度
滑音(Pitch Bend) 0xEn LSB MSB n 代表通道号,LSB 代表低位值,MSB 代表高位值
  • toto.mid 样本中的十六进制数据如下图所示

0x04 触发漏洞,定位异常点

  • 我们选择通过用 IE 加载 winmm.dll 的方式触发漏洞,为了让 IE 浏览器能够触发漏洞,所以在 poc.html 样本中嵌入了一个音频播放器,由音频播放器来调用 toto.mid 文件播放音频从而触发漏洞



  • 第一步设置堆页保护,第二部打开 IE,第三部使用 Windbg 附加进程

  • F5 运行之后将 poc.html 文件拖入 IE,并且允许运行 ActiveX 控件

  • 成功断下异常,可以看出 esi 指向的地址超出了堆空间,之后被堆页保护捕捉到
  • 有经验的可以看出是 winmm.dll 中出了问题

  • IDA 载入这个 winmm.dll,该动态库在 system32 下

  • 下图可以看出是 v25 这个指针越界访问了堆上的数据

  • v25 受 v24 和 v20 影响,通过观察可以发现 v24 受 v2、v9、v11、v13、v21影响(v2 由 wParam 控制)



  • v20 受 v1 影响(v1 也由 wParam 控制)

0x05 OD 调试分析

  • 将 IE 载入 OD 运行,先不要将 html.poc 拖入到 IE 中,之后 shift + F4 对 v2、v9、v11、v13、v21、v23 和 v20 下条件记录断点

  • 设置 v9

  • 设置 v11

  • 设置 v13

  • 设置 v21

  • 设置 v23

  • 设置 v20,最后别忘了断下漏洞触发点断点,这个断点是真的断点

提醒:什么条件记录断点,当程序运行到这个断点时,程序并不会真正的断下,而是会记录表达式的值;一般断点为红色,而条件记录断点为粉色

  • 将 poc.html 文件放入刚刚运行的 IE 之中,之后会在异常触发点断下,按 l 这个快捷小按钮查看日志

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

  • 这个就是样本中的数据,刚好是倒过来的 0x007DB29F

  • 下面就对 v21 下条件断点(shift + F2),看看读取样本数据 0x007DB29F 之后是怎么处理的

  • 重新运行后断下,注意此时 ecx = 007DB29F,之后接着往下调试

  • 首先会将 9F 和 0xF0 做按位与运算,之后将结果与 90 作比较,判断这是打开音符(Note On)还是关闭音符(Note Off);由于 9F0 | 0xF = 90,所以这个是打开音符

提醒:由上可知,打开音符为 0x9n,关闭音符为 0x8n

  • 之后将 9F 和 0xF 做按位与操作,取出通道号 F,之后左移 7 位右移 1 位,最后等于 419

提醒:9F | 0xF = F

  • 最后将 esi(堆基址)+ eax(偏移地址419)

提醒:下面会解释 esi 为什么是堆基址

  • 这时已经知道通道号 F 经过计算之后值为 419,控制着指针的偏移地址,也就是 v24 的值
  • 此时只需要知道 esi,也就是 v20 的值是怎么来的,就可以完全搞清楚漏洞的成因了
  • 首先 v20 由传入的参数 wParam 控制,对 midiOutPlayNextPolyEvent 函数进行交叉引用查询,看看是哪一个函数调用的这个函数

提醒:上面说到 v25 受 v20 和 v24 影响

  • 发现是 midiOutTimerTick函数调用了 midiOutPlayNextPolyEvent 函数,并且把 v6 当作参数传入,而 v6 = gpEmuList
  • gpEmuList 不是参数传入的,所以查询 gpEmuList 的交叉引用,看看是哪一个函数设置了 gpEmuList 这个值,发现是 mseOpen 函数中引用了这个值

  • 这个就是 mseOpen 函数,gpEmuList 由 v5 传入,v5 等于 winmmAlloc 函数分配的堆空间地址

  • 整理一下调用关系

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

这里需要注意的是虽然申请的堆空间大小为 400,可是实际大小不同环境会有不一样的结果,本文测试的时候实际的大小会多出 8 个字节,为 0x408

0x06 漏洞利用

  • 那么如何利用这一个字节来执行任意代码呢?国外安全团队 VUPEN 在其博客上给出了构造的方法,过程十分精彩:
  • 第一步通过 JavaScript 创建一个 html 元素 select,之后给 select 元素设置 60 个属性,并且将第一个属性设置为 String 类型(w0),其余的属性设置任意即可,拥有 60 个属性的 select 大小为 0x408

  • 第二步创建一个 cloned 对象数组大小为 50,之后循环复制 select 元素到 clone



  • 第三步每隔 6 个元素,释放回收第七个元素

  • 这样的话内存空间的分布就如下图所示,只需要等待有漏洞的堆插入到这个精心构造的堆列当中即可,在 windows XP sp3 + IE6 的环境下,成功率接近为百分之百左右

  • 当插入完成之后,漏洞指令会将 String 类型(w0)标识符 0x08 加上 1,变为 0x09 的对象

String 在内存中的标识符为 0x08,对象为 0x09

  • 最后循环调用每个 cloned.w0 属性的 toString() 方法,调用该方法会使每个对象的头 4 个字节当作索引

  • 索引虚表会取出对象的头 4 个字节,之后进行 call 调用,从而执行任意代码

0x07 OD 调试分析

  • 首先关闭堆页保护

  • 负责解析 Html 语言的 IE 模块 mshtml.dll 在处理 html 元素时会调用 CImplAry::clone() 函数和 ClmplAry::DeleteAll() 函数来添加和删除属性的堆空间,上面的申请属性和释放属性就靠这两个方法
  • 使用字符串查找的方法找到 clone 函数和 DeleteAll 函数

  • 这个就是 clone 函数,其中 EnsureSize 函数会给每个元素的属性分配 0x10 大小的堆空间

  • 这个是 DeleteAll 函数,负责释放属性的堆空间

  • 之后下 CImplAry 数组堆首地址、CImplAry 释放堆地址、漏洞函数分配的堆地址(VulBuffer)的条件记录断点





  • 运行之后断在了漏洞触发的汇编指令上

  • 数据窗口跟随后发现此时 esi 指向的是 0x08 这个 String 标识符

  • 查看日志分析,VulBuffer 成功的插入了刚刚释放的空间中去,且大小为 0x408

  • VulBuffer 的地址 + 0x419 刚好为 1E5721,也就是 String 的标识符 0x8

此处多出来的 16 字节应该是堆块头部信息

  • 去除断点继续运行之后,来到了虚表索引

  • 此时 String 的标识符已经变为 0x9

  • 最后会执行 call [ecx+0x4] 的地址

  • 此时 ecx 的值就是 select.w0 对象的头4个字节 0x0c0c1c0c



  • 从而控制了程序的流程,最后通过堆喷射的方法,达到了执行任意代码的目的
  • 关于绕过防护的方法,参考下图

  • 参考资料:0day安全:软件漏洞分析技术 + 漏洞战争

以上就是 CVE-2012-0003 的调试分析,如有错误,欢迎指正

CVE-2012-0003:Microsoft Windows Media Player winmm.dll MIDI 文件堆溢出漏洞调试分析的更多相关文章

  1. CVE-2012-0003 Microsoft Windows Media Player ‘winmm.dll’ MIDI文件解析远程代码执行漏洞 分析

    [CNNVD]Microsoft Windows Media Player ‘winmm.dll’ MIDI文件解析远程代码执行漏洞(CNNVD-201201-110)    Microsoft Wi ...

  2. CVE-2013-0077:Microsoft DirectShow quartz.dll m2p 文件堆溢出漏洞简单分析

    0x01 前言 2012 年 10 月 5 日,exploit-db 漏洞公布站点上发布了 QQplayer.exe 3.7.892 m2p quartz.dll Heap Pointer OverW ...

  3. CVE-2010-2553:Microsoft Cinepak Codec CVDecompress 函数堆溢出漏洞调试分析

    0x01 前言 微软提供一个叫 Cinepak 的视频解码器,通过调用 iccvid.dll 这个动态链接库文件可以使用这个解码器:微软自带的 Windows Media Player(视频音频软件) ...

  4. CVE-2018-0802:Microsoft office 公式编辑器 font name 字段二次溢出漏洞调试分析

    \x01 前言 CVE-2018-0802 是继 CVE-2017-11882 发现的又一个关于 font name 字段的溢出漏洞,又称之为 "第二代噩梦公式",巧合的是两个漏洞 ...

  5. CVE-2017-11882:Microsoft office 公式编辑器 font name 字段栈溢出通杀漏洞调试分析

    \x01 漏洞简介 在 2017 年 11 月微软的例行系统补丁发布中,修复了一个 Office 远程代码执行漏洞(缓冲区溢出),编号为 CVE-2017-11882,又称为 "噩梦公式&q ...

  6. Windows Media Player axWindowsMediaPlayer1 分类: C# 2014-07-28 12:04 195人阅读 评论(0) 收藏

    属性/方法名: 说明: [基本属性] URL:String; 指定媒体位置,本机或网络地址 uiMode:String; 播放器界面模式,可为Full, Mini, None, Invisible p ...

  7. CVE-2012-0158:Microsoft Office MSCOMCTL.ocx 栈溢出漏洞调试分析

    0x01 Lotus Blossom 行动 在 2015 年 6 月,国外安全厂商 Palo Alto Networks 的威胁情报团队 Unit42 发现了一起针对东南亚政府的一次间谍行为,试图获取 ...

  8. win7自带windows media player 已停止工作

    解决方法如下: 在计算机开始,菜单找到控制面板 ,然后打开程序和功能,选择打开或关闭window功能,媒体功能.再取消windows Media Center Windows MediaPlayer选 ...

  9. Windows Media Player安装了却不能播放网页上的视频

    前段时间遇到Windows Media Player安装了却不能播放网页上的视频的问题,在网上查找资料时,发现大部分资料都没能解决我这个问题.偶尔试了网上一牛人的方法,后来竟然解决了.现在再找那个网页 ...

随机推荐

  1. 1.1 Python3基础-前言

    >>返回主目录 Python 交互式代码 Python 脚本式代码 第一段Python代码: print('Hello World!') >>返回主目录

  2. Linux速通 随笔整理

    Linux速通 随笔整理 为了方便阅读,特整理了相关的学习笔记 零.大纲 一.系统安装 二.命令格式 三.文件管理 四.用户群组 五.文件处理 六.系统初始化及监控 七.硬盘初始化 八.网络原理

  3. WPF 基础 - 绘画 1) 线段、矩形、圆弧及填充色

    1. 绘画 1.1 图形类型 Line X1.Y1.X2.Y2,Stroke,StrokeThickness Rectangle 矩形 Ellipse 椭圆 Polygon 多边形(自动闭合) Pol ...

  4. Java流程控制:增强for循环,break&continue,打印99乘法表

    增强for循环:java5引入了一种主要用于数组或集合的增强for循环for(声明语句:表达式){//代码句子} 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配.其作用域限定在循环语 ...

  5. struct2中package的参数解析

    struct2框架的核心组件是action和拦截器,它使用包来管理action和拦截器,每个包就是多个action.多个拦截器引用的集合.在struct.xml中,package元素用于定义包的配置, ...

  6. Codeforces Round #541 F. Asya And Kittens

    题面: 传送门 题目描述: Asya把N只(从1-N编号)放到笼子里面,笼子是由一行N个隔间组成.两个相邻的隔间有一个隔板. Asya每天观察到有一对想一起玩,然后就会把相邻的隔间中的隔板取出来,使两 ...

  7. Xshell(远程)连接不上linux服务器(防火墙介绍)

    一.原因 远程(ssh)连接不上linux服务器的大多数原因都是因为本地服务器的防火墙策略导致的,因此我们想ssh远程能够连接上服务器,有两种方法: 修改防火墙策略 关闭防火墙 二.防火墙服务介绍 1 ...

  8. HTML的基础语法

    区别于c语言这类高级语言,HTML不是编程语言,而好似一种描述型语言,用于描述网页中内容的显示方式. HTML标记以<>来进行标记.HTML中的标记按其是否成对出现,可以分为单标记和双标记 ...

  9. spring-boot记录sql探索

    目标记录每次请求内的http.es.mysql耗时,本篇讨论mysql部分 为什么说要探索,这不是很简单的事么?但是能满足以下几点么? 能记录limit等参数 能将参数和sql写一起,能直接使用 能记 ...

  10. 电影AI修复,让重温经典有了新的可能

    摘要:有没有一种呈现,不以追求商业为第一目的,不用花大价钱,不用翻拍,没有画蛇添足,低成本的可共赏的让经典更清晰? 本文分享自华为云社区<除了重映和翻拍,重温经典的第三种可能>,原文作者: ...