/*************************************************************** nmap stub / v1.0 This file reads in nmap (v2.x human) output, puts it into port and host structures, and then can call whatever routines you want (per host) to check for exploits, etc. If you have any suggestions, fixes, etc, let me know rfpuppy@iname.com .rain.forest.puppy. ---------------------------------------------------------------- global information the stub provides: ----In INDEX mode:---- int tcp_ports[65535] int udp_ports[65535] These two structures contain the port information (that actual state of the port). Initially set to 0 (port not found), changed to 1 (open). So, to check if port 80 (http) is open: if(tcp_ports[80]){ //port is open..// } ---In LIST mode:---- struct portnode{ unsigned int port; unsigned int state;} portnode tcp_ports[2048] portnode udp_ports[2048] Use in conjunction with tpnum/upnum (total number of ports). Example: for(int x=0; x < tpnum; x++){ // do something with tcp_ports[x] // } Perl equivalent: foreach $found_port (@port_list) { // do whatever // } ----In all modes:---- char name[1024] char ip[1024] char os[1024] unsigned int tpnum unsigned int upnum int return_value Resolved name of host (NULL string if not known), IP address in string format, and OS guess (if available...NULL string if not known). Tpnum is the number of tcp ports in list; upnum is the number of udp ports in list. Return_value is what's given when the program exits. ---------------------------------------------------------------- Todo: read in actual state and adjust port value (tcp_ports[x] in INDEX, tcp_ports[x].state in LIST). Figure 1 for open, 2 for filtered, 3 for firewalled, etc. ****************************************************************/ #include /* define INDEX for index of ports, undefine INDEX for list of ports */ #define INDEX /* define STATIC_FILE to specify a specific file to always open. Undefine it to take it from ARGV */ #undef STATIC_FILE /* vv--- remove the const if you want to change the debug value inline */ const int debug=0; /* set to 1 just to see what's going on */ #ifdef STATIC_FILE #define STATIC_FILE_NAME "nmap.out" #endif #ifdef INDEX int tcp_ports[65535]; int udp_ports[65535]; #define MAX 65535 #else struct portnode { unsigned int port; unsigned int state; } portnode; struct portnode tcp_ports[2048]; struct portnode udp_ports[2048]; #define MAX 2048 #endif char name[1024]; char ip[1024], os[1024]; unsigned int tpnum=0; unsigned int upnum=0; int return_value=0; int y; void yourfunc(void){ /*********************************************************** Insert your function/code here to be called per host ***********************************************************/ /* this is example code */ #ifdef INDEX /* demo of how to access index of ports */ printf("Checking %s, ip: %s", name, ip); if (os[0] != '\0') printf(" OS: %s\n", os); else printf("\n"); printf("Found %i TCP ports, %i UDP ports\n", tpnum, upnum); if (tcp_ports[80]) printf("Seem to be running a web server\n"); if (tcp_ports[21]) printf("Seem to be running a ftp server\n"); if (tcp_ports[23]) printf("Seem to be running telnetd\n"); printf("\n"); #else /* demo of how to access list of ports */ printf("Checking %s, ip: %s", name, ip); if (os[0] != NULL) printf(" OS: %s\n", os); else printf("\n"); printf("Found %i TCP ports, %i UDP ports\n", tpnum, upnum); printf("Open TCP ports:"); for (y = 0; y < tpnum; y++) printf(" %i", tcp_ports[y].port); printf("\n\n"); #endif /* end of example code */ /** End of your code/function *****************************/ } FILE *fp; char line[1024], copy[1024]; char s1[1024], s2[1024], s3[1024]; int c,tp; unsigned int x, gothost=0; int main(int argc, char *argv[]){ char filename[256]; /* shameless plug. ;-) */ printf("Nmap stub by .rain.forest.puppy. rfpuppy@iname.com\n"); for (x = 0; x < MAX; x++) #ifdef INDEX tcp_ports[x] = udp_ports[x] = 0; #else tcp_ports[x].state=tcp_ports[x].port=udp_ports[x].state=udp_ports[x].port=0; #endif #ifdef STATIC_FILE filename=STATIC_FILE_NAME; #else if (argc < 2){ printf("You need to specify the nmap input file on the commandline\n"); return -1;} strncpy(filename,argv[1],255); #endif /*********************************************************** If you're going to process commandline switches, here's a good place to do it. If you do commandline switches, I suggest you define STATIC_FILE, and then make a switch to specify the filename. Put the input file name into 'filename'. By defining STATIC_FILE, you'll have a default filename (defined in STATIC_FILE_NAME) ***********************************************************/ /* your getopts code */ /**********************************************************/ if ((fp=fopen(filename,"r")) == NULL){ perror("fopen"); return -1;} fgets(line,sizeof(line)-1,fp); do { /* main decoding loop */ if(c = sscanf(line,"Interesting ports on %1023s (%1023[^)]):",s1,s2)){ if(gothost){ /* we run function on first host when we start the record for the second host */ yourfunc(); for (x=0; x < MAX; x++) #ifdef INDEX tcp_ports[x]=udp_ports[x]=0; #else tcp_ports[x].state=tcp_ports[x].port=udp_ports[x].state=udp_ports[x].port=0; #endif strcpy(name,"\0"); /* no need to clear ip, as it */ strcpy(os,"\0"); /* will be overwritten below */ tpnum = upnum = 0; } gothost = 1; if (c == 2){ strncpy(name, s1, 1024); strncpy(ip, s2, 1024); } else sscanf(s1, "(%1024[^)])", ip); if (debug) printf("Setting hostname: %s ip: %s\n", s1, s2); fgets(line,sizeof(line)-1,fp); } if(!strcmp(line,"Port State Protocol Service\n")){ if (debug) printf("Adding ports:"); fgets(line, sizeof(line)-1,fp); while(strcmp(line, "\n")){ sscanf(line,"%i%20[ ]%20[^ ]%30[ ]%20[^ ]%1024s",&tp,s1,s2,s1,s3,s1); if (debug) printf(" %i/%s (%s)",tp,s3,s2); if(!strncmp(s3,"tcp",1023)) { #ifdef INDEX tcp_ports[tp]=1; #else tcp_ports[tpnum].port=tp; tcp_ports[tpnum].state=1; #endif tpnum++; } else { #ifdef INDEX udp_ports[tp]=1; #else udp_ports[tpnum].port=tp; udp_ports[tpnum].state=1; #endif upnum++;} fgets(line, sizeof(line)-1, fp);} if (debug) printf("\nAdded %i TCP ports, %i UDP ports\n",tpnum,upnum); fgets(line, sizeof(line) - 1, fp);} if(sscanf(line,"Remote operating system guess: %1024[^\n]", s1)){ strncpy(os, s1, 1024); if (debug) printf("OS: %s\n", s1); } } while(fgets(line, sizeof(line) - 1, fp)); if (gothost) yourfunc(); /* catch the last host */ fclose(fp); /*********************************************************** Do any cleanup you need to here ***********************************************************/ return return_value;}