首页
社区
课程
招聘
[原创]对Easy RM to MP3 Converter 2.7.3.700的栈溢出漏洞分析
发表于: 2014-5-29 16:37 5112

[原创]对Easy RM to MP3 Converter 2.7.3.700的栈溢出漏洞分析

2014-5-29 16:37
5112

说实话自己一直对如何定位漏洞点很头痛,看着别人下各种各样的断点,栈回溯等技巧,总是觉得似懂非懂。不同的软件,不同的漏洞类型有不同的技巧,这需要慢慢长期积累经验。

最近偶然看到一篇文章,《漏洞分析第一次--漏洞发现》,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直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (7)
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
2
占楼,exploit编写系列教程很经典...,可以尝试一下win7,win8下面的利用
2014-5-29 17:25
0
雪    币: 41
活跃值: (159)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
唉,主要是动态获取kernel32.dll地址的问题我还没搞定
2014-5-30 09:52
0
雪    币: 3171
活跃值: (76)
能力值: (RANK:250 )
在线值:
发帖
回帖
粉丝
4
分析的不错,
win7下 kernel32的地址的查询,可以针对性调试下,判断某个位置的字符就能准确得到了
2014-5-30 10:12
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
5
不同win平台动态获取kernel32.dll地址的问题,在exploit教程中也可以找到答案的。
2014-5-30 22:47
0
雪    币: 41
活跃值: (159)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
应该是第九篇,我仔细看看,有不懂的还要请教泉哥哈
2014-5-30 22:59
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
7
获取kernel32.dll的地址  有通用的方法 很稳定  偶写shellcode每次都用
2014-5-30 23:00
0
雪    币: 41
活跃值: (159)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
安同学能否分享出来?我在这里先谢谢您了。
2014-5-30 23:15
0
游客
登录 | 注册 方可回帖
返回
//