相关链接:https://www.exploit-db.com/exploits/14886/
环境介绍:XP Professional sp 3 Movie Maker 2.1.4026.0
漏洞描述:
https://technet.microsoft.com/zh-cn/library/security/ms10-016.aspx
官方说明了是一个缓冲区溢出漏洞且2.1版本是受漏洞影响的。
重现漏洞:
下载文章中提供的压缩包,打开Movie Maker,用windbg attach后加载exploit.mswmm文件。断在了这里(没断在这也算正常)
由于ecx已经被覆盖为0x90909090,所以调用虚函数时导致了异常。查看函数调用堆栈,观察之前的执行流程。
顺便用IDA打开漏洞模块,便于后续分析。
在IDA中定位CDocManager::ExtractData函数中的奔溃的地址,ecx = [eax] = [var_10] ,向上浏览代码var_10来自于CDocManager::GetStream,也可以在CrashPoint 按F5进行跟踪。
对01180BC8处下断用windbg重新调试,重新调试发现异常的位置不对了而且很难重现之前的异常情况,然后就开始找原因。给MessageBox下断查看调用堆栈发现流程是一样的,只是不触发异常。
这里我就开始想错了,考虑成了流程一致,结果不一致,往输入不一致的方向考虑了。然后就各种找原因,比如删除临时文件之类的。最后一无所获,只能回来重新分析之前那个异常。没有想到堆溢出,因为溢出的位置会导致流程不一样。所以也会有各种不同的异常出现。所以对异常处的分析应该更多一点,应该尽早确认出是一个堆溢出。
根据调用堆栈,先根据CDocManager::ExtractData的返回地址 0118155f 对 0118155A 下断,因为 CDocManager::Extract 函数会调用多次。断下后
再对01180BC8处下断,var_10是一个IStream指针,断下后查看还是空的。执行完CDocManager::GetStream后就有值了。
执行前:
执行后:
异常的原因就是这个对象的虚表变成了0x90909090,继续跟踪下去。
到达 CDocManager::CSmartStream::Read 读取相关的函数,读取的数据大小为0x1111,那么肯定有一个存放数据的buffer,查看该函数的参数。跟进后发现该函数调用了ole32!CExposedStream::Read 且IDA提示参数2是个指针。记录下执行前后的数据,发现确实写入了数据。
跟踪该参数来源,在上层函数中发现该参数来自于堆。
查看该地址的相关信息,发现该堆块大小只有0x20,而复制的大小有0x1111导致堆溢出。