[原创]对Easy RM to MP3 Converter 2.7.3.700的栈溢出漏洞分析
发表于:
2014-5-29 16:37
5112
[原创]对Easy RM to MP3 Converter 2.7.3.700的栈溢出漏洞分析
说实话自己一直对如何定位漏洞点很头痛,看着别人下各种各样的断点,栈回溯等技巧,总是觉得似懂非懂。不同的软件,不同的漏洞类型有不同的技巧,这需要慢慢长期积累经验。
最近偶然看到一篇文章,《漏洞分析第一次--漏洞发现》,11年写的,作者当时还是新手,在大牛K_K的指导下完成。分析的是一个普通的栈溢出,原文地址在这里:http://hi.baidu.com/chill_bupt/item/d540f4394b6995dc392ffa0c。看完后自己也受到一些启发,感觉按照K_K的思路,很多栈溢出类型的漏洞都可以用此方式来分析,所以自己也试着分析了一个,就是exploit编写系列教程第一篇里的那个Easy RM to MP3 Converter 2.7.3.700的栈溢出漏洞。我下载了原作者的exploit,发现在windows xp sp3简体中文版下已经不能运行(当时分析的环境是windows xp sp2 en),并且在调试中发现缓冲区大小也和原作者的分析有差异(他用的是metasploit的一个小工具计算的),于是自己从头到尾分析了这个漏洞,并写出弹计算器的exploit。
软件我上传到了附件中。
还记得当时的场景吗?构造一个恶意的m3u文件,填了20000个A,没崩,填了30000个,崩掉了,eip被改为41414141。我就拿这个填了30000个A的m3u来分析。
环境:windows xp sp3 professional 简体中文版(虚拟机下)
调试器:Immunity Debugger 1.85
用调试器打开Easy RM to MP3 Converter,加载m3u文件,崩掉,eip被改为41414141。
很显然崩溃是因为返回这个问题函数的上层函数的时候发生的。虽然返回失败,但这个问题函数还会调用其他函数,只要调用了其他函数,那么从这个问题函数的栈帧开始向低地址搜索,肯定会发现其他函数的返回地址,肯定返回到了这个问题函数中。然后,就好办了。
在栈帧中向低地址找,直到没有那一堆A。
再往上是一些参数,然后esp-8920,esp-8924是现在ebx的值,esp-8928是现在ebp的值。再往上msvcrt的那个返回地址不用管它,esp-8930是现在edi的值,然后就是返回地址了。
在Immunity Debugger中转到0041E9D8,当单步RETN 4后,程序崩掉。
现在上IDA,打开Easy RM to MP3 Converter,转到0041E9D8,来到这里:
按空格键,转换为视图模式:
可以看出这个函数的名字是:sub_41E2B0,也就是返回失败前最后调用的那个函数,也就是上文提到的问题函数。双击它,来到这个函数开始的地方。
顺着跳转往下找,很快发现了复制字符串,计算字符串长度的东西:
在到达这个问题函数的末尾前,还有一些这样跟复制有关的,那怎么确定到底是在哪里出现问题,发生了溢出?看来只有调试一下了。
先来看看栈上的情况,当最后崩掉时,esp=000FFD38,那个问题函数最后返回时是RETN 4,所以,存放返回地址的地方是000FFD38 - 8 =000FFD30
要复制东西,应该是把esi指向的东西复制到edi指向的东西。在这个问题函数开始的地方设一个断点,在栈中来到000FFD30(此时存放的还是返回地址),把栈的位置锁定,然后单步,同时观察ESI,EDI,注意REP MOVS之类的指令,如果执行完某条指令后000FFD30处变成一堆A,那就说明上一条指令发生了溢出。
到0041E3F6时,edi的值指向一堆A。那么溢出应该发生在上一条指令:
0041E3F0 |. FF93 72640000 CALL DWORD PTR DS:[EBX+6472]
重新加载,在这条指令下断点:
0041E3F0 |. FF93 72640000 CALL DWORD PTR DS:[EBX+6472]
仔细观察栈上000FFD30处的数据:
执行前,000FFD30处的数据还是返回地址,执行后,000FFD30处的数据就成一堆A了。
应该就是它了。
重新加载,F7单步步入,来到10008D40,module MSRMfilt。Alt+E查看加载的模块,实际上对应的是安装目录下的MSRMfilter03.dll这个文件。
用IDA打开这个dll文件,来到10008D40,切换到视图模式,这个函数的逻辑很简单,很快找到复制字符串的地方:
当然,也可以用调试器单步调试一下:
10008D40 > 68 C0000000 PUSH 0C0
10008D45 68 68940310 PUSH MSRMfilt.10039468 ; ASCII "D:\Mpf2.0\MplayerMod\dll_interface\PlayListInterface.c"
10008D4A 68 48950310 PUSH MSRMfilt.10039548 ; ASCII "Debug: Playlist_FindNextItem enter. %s(%u)"
10008D4F 6A 05 PUSH 5
10008D51 E8 8A000000 CALL MSRMfilt.10008DE0
10008D56 A1 00D60410 MOV EAX,DWORD PTR DS:[1004D600]
10008D5B 6A 01 PUSH 1
10008D5D 50 PUSH EAX
10008D5E E8 EDDAFFFF CALL MSRMfilt.10006850
10008D63 83C4 18 ADD ESP,18
10008D66 85C0 TEST EAX,EAX
10008D68 74 44 JE SHORT MSRMfilt.10008DAE
10008D6A 56 PUSH ESI ; 001046AF
10008D6B 57 PUSH EDI ; 000FFD30(栈上存放返回地址的位置)
10008D6C 8BF8 MOV EDI,EAX
10008D6E 83C9 FF OR ECX,FFFFFFFF
10008D71 33C0 XOR EAX,EAX
10008D73 68 CD000000 PUSH 0CD
10008D78 F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; EDI指向C:\Documents and Settings\Administrator\桌面\AAAAAAAAAAA
10008D7A F7D1 NOT ECX
10008D7C 2BF9 SUB EDI,ECX
10008D7E 68 68940310 PUSH MSRMfilt.10039468 ; ASCII "D:\Mpf2.0\MplayerMod\dll_interface\PlayListInterface.c"
10008D83 8BD1 MOV EDX,ECX
10008D85 8BF7 MOV ESI,EDI ; ESI指向C:\Documents and Settings\Administrator\桌面\AAAAAAAAAAA
10008D87 8B7C24 14 MOV EDI,DWORD PTR SS:[ESP+14] ; EDI指向OOOF9730,一开始那里是一堆0
10008D8B 68 20950310 PUSH MSRMfilt.10039520 ; ASCII "Debug: Playlist_FindNextItem ok. %s(%u)"
10008D90 C1E9 02 SHR ECX,2
[COLOR="Red"]10008D93 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI][/COLOR] ; 在这里发生溢出,覆盖返回地址!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: