/* webscan.c - 1999 (c) Mixter */ /* compile: gcc -O2 -Wall webscan.c -o webscan */ #define INITIAL_TIMEOUT 5 // how long to wait for a connection #define WAIT_FORK 1500000 // wait between forks in ms #define VERSION "ver.log" #define VULN "vuln.log" #define STATUSLOG "status.log" #include #include #include #include #include #include #include #include #include #include #include #include #include #define SSA sizeof(struct sockaddr) #define SOX socket(AF_INET,SOCK_STREAM,0) void usage(char *name, char *text); // print usage & die int validip(char *); // check and correct ip address void fchk(FILE *); // check a file void timedout(int); // dummy sighandler function int background(void); // background a process void sk4n(char *); // log services for one ip int y2ksucks (char *); // strstr replacement char *buff[100]; char *cginame[100]; int timeout = INITIAL_TIMEOUT; int main(int argc,char **argv) { FILE *data,*err; char ip[30]; int pid; if((argc!=2)) usage(argv[0],""); fprintf(stderr,"web scan 1.1 by Mixter\n"); fprintf(stderr,"scanning from %s (pid: %d)\n" ,argv[1] ,(pid=background())); signal(SIGHUP,SIG_IGN); signal(SIGCHLD,SIG_IGN); // zombies suck fchk(data=fopen(argv[1],"r")); fchk(err=fopen(STATUSLOG,"a")); fprintf(err,"Started new session. File: %s, PID: %d\n",argv[1],pid); fflush(err); buff[1] = "GET /cgi-bin/unlg1.1 HTTP/1.0\n\n"; buff[2] = "GET /cgi-bin/rwwwshell.pl HTTP/1.0\n\n"; buff[3] = "GET /cgi-bin/phf HTTP/1.0\n\n"; buff[4] = "GET /cgi-bin/Count.cgi HTTP/1.0\n\n"; buff[5] = "GET /cgi-bin/test-cgi HTTP/1.0\n\n"; buff[6] = "GET /cgi-bin/nph-test-cgi HTTP/1.0\n\n"; buff[7] = "GET /cgi-bin/nph-publish HTTP/1.0\n\n"; buff[8] = "GET /cgi-bin/php.cgi HTTP/1.0\n\n"; buff[9] = "GET /cgi-bin/handler HTTP/1.0\n\n"; buff[10] = "GET /cgi-bin/webgais HTTP/1.0\n\n"; buff[11] = "GET /cgi-bin/websendmail HTTP/1.0\n\n"; buff[12] = "GET /cgi-bin/webdist.cgi HTTP/1.0\n\n"; buff[13] = "GET /cgi-bin/faxsurvey HTTP/1.0\n\n"; buff[14] = "GET /cgi-bin/htmlscript HTTP/1.0\n\n"; buff[15] = "GET /cgi-bin/pfdispaly.cgi HTTP/1.0\n\n"; buff[16] = "GET /cgi-bin/perl.exe HTTP/1.0\n\n"; buff[17] = "GET /cgi-bin/wwwboard.pl HTTP/1.0\n\n"; buff[18] = "GET /cgi-bin/www-sql HTTP/1.0\n\n"; buff[19] = "GET /cgi-bin/view-source HTTP/1.0\n\n"; buff[20] = "GET /cgi-bin/campas HTTP/1.0\n\n"; buff[21] = "GET /cgi-bin/aglimpse HTTP/1.0\n\n"; buff[22] = "GET /cgi-bin/glimpse HTTP/1.0\n\n"; buff[23] = "GET /cgi-bin/man.sh HTTP/1.0\n\n"; buff[24] = "GET /cgi-bin/AT-admin.cgi HTTP/1.0\n\n"; buff[25] = "GET /cgi-bin/filemail.pl HTTP/1.0\n\n"; buff[26] = "GET /cgi-bin/maillist.pl HTTP/1.0\n\n"; buff[27] = "GET /cgi-bin/jj HTTP/1.0\n\n"; buff[28] = "GET /cgi-bin/info2www HTTP/1.0\n\n"; buff[29] = "GET /cgi-bin/files.pl HTTP/1.0\n\n"; buff[30] = "GET /cgi-bin/finger HTTP/1.0\n\n"; buff[31] = "GET /cgi-bin/bnbform.cgi HTTP/1.0\n\n"; buff[32] = "GET /cgi-bin/survey.cgi HTTP/1.0\n\n"; buff[33] = "GET /cgi-bin/AnyForm2 HTTP/1.0\n\n"; buff[34] = "GET /cgi-bin/textcounter.pl HTTP/1.0\n\n"; buff[35] = "GET /cgi-bin/classifieds.cgi HTTP/1.0\n\n"; buff[36] = "GET /cgi-bin/environ.cgi HTTP/1.0\n\n"; buff[37] = "GET /cgi-bin/wrap HTTP/1.0\n\n"; buff[38] = "GET /cgi-bin/cgiwrap HTTP/1.0\n\n"; buff[39] = "GET /cgi-bin/guestbook.cgi HTTP/1.0\n\n"; buff[40] = "GET /cgi-bin/edit.pl HTTP/1.0\n\n"; buff[41] = "GET /cgi-bin/perlshop.cgi HTTP/1.0\n\n"; buff[42] = "GET /_vti_inf.html HTTP/1.0\n\n"; buff[43] = "GET /_vti_pvt/service.pwd HTTP/1.0\n\n"; buff[44] = "GET /_vti_pvt/users.pwd HTTP/1.0\n\n"; buff[45] = "GET /_vti_pvt/authors.pwd HTTP/1.0\n\n"; buff[46] = "GET /_vti_pvt/administrators.pwd HTTP/1.0\n\n"; buff[47] = "GET /_vti_bin/shtml.dll HTTP/1.0\n\n"; buff[48] = "GET /_vti_bin/shtml.exe HTTP/1.0\n\n"; buff[49] = "GET /cgi-dos/args.bat HTTP/1.0\n\n"; buff[50] = "GET /cgi-win/uploader.exe HTTP/1.0\n\n"; buff[51] = "GET /cgi-bin/rguest.exe HTTP/1.0\n\n"; buff[52] = "GET /cgi-bin/wguest.exe HTTP/1.0\n\n"; buff[53] = "GET /scripts/issadmin/bdir.htr HTTP/1.0\n\n"; buff[54] = "GET /scripts/CGImail.exe HTTP/1.0\n\n"; buff[55] = "GET /scripts/tools/newdsn.exe HTTP/1.0\n\n"; buff[56] = "GET /scripts/fpcount.exe HTTP/1.0\n\n"; buff[57] = "GET /cfdocs/expelval/openfile.cfm HTTP/1.0\n\n"; buff[58] = "GET /cfdocs/expelval/exprcalc.cfm HTTP/1.0\n\n"; buff[59] = "GET /cfdocs/expelval/displayopenedfile.cfm HTTP/1.0\n\n"; buff[60] = "GET /cfdocs/expelval/sendmail.cfm HTTP/1.0\n\n"; buff[61] = "GET /iissamples/exair/howitworks/codebrws.asp HTTP/1.0\n\n"; buff[62] = "GET /iissamples/sdk/asp/docs/codebrws.asp HTTP/1.0\n\n"; buff[63] = "GET /msads/Samples/SELECTOR/showcode.asp HTTP/1.0\n\n"; buff[64] = "GET /search97.vts HTTP/1.0\n\n"; buff[65] = "GET /carbo.dll HTTP/1.0\n\n"; cginame[1] = "UnlG - backd00r "; cginame[2] = "THC - backd00r "; cginame[3] = "phf..classic :) "; cginame[4] = "Count.cgi "; cginame[5] = "test-cgi "; cginame[6] = "nph-test-cgi "; cginame[7] = "nph-publish "; cginame[8] = "php.cgi "; cginame[9] = "handler "; cginame[10] = "webgais "; cginame[11] = "websendmail "; cginame[12] = "webdist.cgi "; cginame[13] = "faxsurvey "; cginame[14] = "htmlscript "; cginame[15] = "pfdisplay "; cginame[16] = "perl.exe "; cginame[17] = "wwwboard.pl "; cginame[18] = "www-sql "; cginame[19] = "view-source "; cginame[20] = "campas "; cginame[21] = "aglimpse "; cginame[22] = "glimpse "; cginame[23] = "man.sh "; cginame[24] = "AT-admin.cgi "; cginame[25] = "filemail.pl "; cginame[26] = "maillist.pl "; cginame[27] = "jj "; cginame[28] = "info2www "; cginame[29] = "files.pl "; cginame[30] = "finger "; cginame[31] = "bnbform.cgi "; cginame[32] = "survey.cgi "; cginame[33] = "AnyForm2 "; cginame[34] = "textcounter.pl "; cginame[35] = "classifields.cgi"; cginame[36] = "environ.cgi "; cginame[37] = "wrap "; cginame[38] = "cgiwrap "; cginame[39] = "guestbook.cgi "; cginame[40] = "edit.pl "; cginame[41] = "perlshop.cgi "; cginame[42] = "_vti_inf.html "; cginame[43] = "service.pwd "; cginame[44] = "users.pwd "; cginame[45] = "authors.pwd "; cginame[46] = "administrators "; cginame[47] = "shtml.dll "; cginame[48] = "shtml.exe "; cginame[49] = "args.bat "; cginame[50] = "uploader.exe "; cginame[51] = "rguest.exe "; cginame[52] = "wguest.exe "; cginame[53] = "bdir - samples "; cginame[54] = "CGImail.exe "; cginame[55] = "newdsn.exe "; cginame[56] = "fpcount.exe "; cginame[57] = "openfile.cfm "; cginame[58] = "exprcalc.cfm "; cginame[59] = "dispopenedfile "; cginame[60] = "sendmail.cfm "; cginame[61] = "codebrws.asp "; cginame[62] = "codebrws.asp 2 "; cginame[63] = "showcode.asp "; cginame[64] = "search97.vts "; cginame[65] = "carbo.dll "; while(!feof(data)) { fscanf(data,"%s\n",ip); if(validip(ip)==1) { usleep(WAIT_FORK); // wait between fork()'s (1/2 second default) if ((pid=vfork()) < 0) { perror("fork"); exit(1); } if (pid==0) // child { sk4n(ip); // collect data for this host & save into files raise(9); return 0; } } else fprintf(err,"Invalid IP: %s\n",ip); } while(1) {} sleep(120); // wait for the last childs fprintf(err,"Finished session. File: %s\n",argv[1]); return 0; } /* parts from this function are from * cgiscan1.35 (c) [CKS & Fdisk] * and httpver (c) Shok */ void sk4n (char *host) { struct sockaddr_in sin; int sock,i,numbytes,count=0; char cgibuff[1024]; char buffer[170]; char *p; FILE *f1,*f2; sin.sin_family=AF_INET; sin.sin_port=htons(80); sin.sin_addr.s_addr=inet_addr(host); sock=socket(AF_INET, SOCK_STREAM, 0); alarm(0); signal(SIGALRM,timedout); alarm(timeout); connect(sock, (struct sockaddr*)&sin, sizeof(sin)); alarm(0); send(sock, "GET / HTTP/1.0\n\n",16,0); fchk(f1=fopen(VERSION,"a")); fchk(f2=fopen(VULN,"a")); for (i=0;i<5;i++) { bzero(buffer,sizeof(buffer)); if((numbytes=recv(sock, buffer, 169, 0)) < 1) break; p=strstr(buffer, "Server"); if(p==NULL) continue; else *p+=7; fprintf(f1,"%s - %s\n", host , p); } close(sock); while(count++ <= 65) { sock=socket(AF_INET, SOCK_STREAM, 0); alarm(0); signal(SIGALRM,timedout); alarm(timeout); connect(sock, (struct sockaddr*)&sin, sizeof(sin)); alarm(0); bzero(cgibuff,sizeof(cgibuff)); send(sock, buff[count],strlen(buff[count]),0); recv(sock, cgibuff, sizeof(cgibuff),0); if(y2ksucks(cgibuff)) fprintf(f2,"%s - %s\n",host,cginame[count]); close(sock); } } void usage(char *name,char *text) { printf("usage: %s %s\n",name,text); exit(EXIT_FAILURE); } int validip(char *ip) { int a,b,c,d,*x; sscanf(ip,"%d.%d.%d.%d",&a,&b,&c,&d); x=&a; if(*x < 0) return 0; if(*x > 255) return 0; x=&b; if(*x < 0) return 0; if(*x > 255) return 0; x=&c; if(*x < 0) return 0; if(*x > 255) return 0; x=&d; if(*x < 0) return 0; if(*x > 255) return 0; sprintf(ip,"%d.%d.%d.%d",a,b,c,d); // truncate possible garbage data return 1; } void fchk(FILE *fp) { if(fp==NULL) { fprintf(stderr,"Error opening file or socket.\n"); exit(EXIT_FAILURE); } return; } void timedout(int sig) { alarm(0); raise(9); } int background() { int pid; signal(SIGCHLD,SIG_IGN); pid = fork(); if(pid>0) { sleep(1); exit(EXIT_SUCCESS); // parent, exit } if(pid==0) { signal(SIGCHLD,SIG_DFL); return getpid(); // child, go on } return -1; // fork failed } int y2ksucks (char *buf) { int i; for (i = 2; i <= (int) strlen (buf); i++) if ((buf[i] == '0') && (buf[i - 1] == '0') && (buf[i - 2] == '2') && (buf[i + 1] != '0')) return 1; return 0; }