ღ Miranda

CVE-2010-2553 堆溢出分析

前言

CVE-2010-2553Windows Media Playercinepak解码组件iccvid.dll中的一个堆溢出漏洞。

环境

系统: windows XP SP3
软件: Windows Media Player 10.00.00.4068

poc

调试分析

附加到程序,打开poc.avi,会崩溃在一条mov指令:

用栈回溯看看是哪里调用的有漏洞的函数:

漏洞函数就在sub_73b721ae中,这里要对73b7cbee下断点,但iccvid.dll模块在加载poc.avi后才会加载,可以用模块加载断点来下断点:

IDA中这个函数的声明是:

这个函数有7个参数,

为了读懂函数流程,需要了解关于aviCinepak的结构。

avi和Cinepak

avi文件结构是一个一个块的形式,每个数据块包括4字节的标记,数据块大小和数据,一般文件以RIFF开头,然后跟着是大小,然后数据部分是一个标记为AVI的块,包含三个子块,信息块,数据块和索引块,信息块又包含了几个子块,有固定的模式,在poc.py中就是aviHeaders段。信息块后有一段填充,是垃圾数据,是poc.py中的padding段。数据块是我们可以控制的头部有movi标签,对应poc.pymovi_tag段。尾部还有索引块,对应idx_tag

数据块使用的是Cinepak压缩的数据,微软默认使用cinepak的压缩格式来压缩.avi视频文件,处理的库是iccvud.dllCVDecompress是用来解压cinepak压缩流的,被压缩的流都包含了一个frame header,然后会有一些strip

frame header结构如下,对应于poc中的cinepak_codec_data1number_of_coded_strips,将poc中的数据填进去:

后面是一个个的编码块,由strip headerstrip chunk(Codebooks+Frame Vectors)组成。strip header结构如下:

strip chunk结构:

poc.py中的cinepak_codec_data2就是编码块,可以得到各段数据:

更多可以参考https://multimedia.cx/mirror/cinepak.txt

继续调试

继续调试,单步进73b7cbeecall

这里比较跳转后进入处理流程,比较数据大小是否大于0x20,小于的话就不处理:

获取长度:

将数据流的起始地址赋给esi016adaf8处就是Cinepak压缩的数据,就是是poc.py中的:

查看内存:

这里判断长度数据是否为整数:

判断大小是否小于0xa,小于的话就不处理,0xa刚好是frame header的大小:

esi指针加上frame header大小,指向strip header:

获取strip数量:

获取压缩数据长度,就是cinepak_codec_data2的长度,判断是否大于0x16:

判断strip ID的类型:

获取strips top ystrips bottom y相减然后乘以一个常数:

每次处理0x10的数据,直到小于0x16为止:

获取CVID Chunk ID,当为0x11时才会进入复制的流程:

这里开始处理我们填入的数据:

这里把rep movs的目标地址和来源地址放入ediesi中:

每次填充完堆上的地址都会增加0x2000

esi是堆上的地址:

这个堆的大小是0x6000

重新调试一下,在73b722c6下断点:

这个堆是从0014e690开始的0x6000大小的堆。每次ediesi的值如下:

第三次时目标地址已经超出了堆的范围,造成了堆溢出。当编码条数量超过三个并且ID\x11时就会造成溢出。

发表评论

电子邮件地址不会被公开。