## ## New Wikto style CGI checking - this is a drop-in replacement for ## the old is_cgi_installed_ka. The brave can disable no404.nasl. ## The functions are (C) SensePost Research 2004/2005 ## Hacked together by Roelof Temmingh ## ## PS: see http://www.sensepost.com/research/wikto for how wikto works ## function is_cgi_installed_ka(item, port, location, ext){ local_var s,r,dir,slash,dirs,compare,URL,real_location,real_ext,location,ext,kbitem,dummyURL; if(item[0] != "/") { dirs = cgi_dirs(); slash = "/"; } else { dirs = make_list(""); slash = ""; } foreach dir (dirs) { URL=dir+slash+item; #test if the location is set if (strlen(location)<=0){ real_location=http_convertURL2directory(URL:URL); } else {real_location=location;} #test if the ext is set if (strlen(ext)<=0){ real_ext=http_convertURL2extention(URL:URL); } else {real_ext=ext;} #OK build the dummy dummyURL=real_location+"SP_never_SP."+real_ext; if (debug_level){display("Real URL is:"+URL+"\r\n");} if (debug_level){display("Dummy URL is:"+dummyURL+"\r\n");} r = http_keepalive_send_recv(port:port, data:http_get(item:URL, port:port)); if( r == NULL ) return NULL; #now do the dummy request #check if its in the KB.. kbitem=real_location+real_ext; kbitem="www/"+port+"/"+kbitem; s = get_kb_item(kbitem); if (strlen(s)<=0){ s = http_keepalive_send_recv(port:port, data:http_get(item:dummyURL, port:port)); #save in KB set_kb_item(name:kbitem,value:s); } compare=compareData(dataone:s,datatwo:r); if (debug_level){display("compare for "+URL+" is:"+compare+"\r\n");} if (compare < 50 ){return 1;} #----------------^^ fiddle here if you want to else {return 0;} } } # ------------------------------------------------------------# # Really pre-historic content compare # Baysian filters anyone? # Neural networks ? # function compareData(dataone,datatwo){ local_var total, thing, totallength,dataa,datab,ta,tb,one,two; if (debug_level){display(dataone);} if (debug_level){display("=----------------------------\r\n");} if (debug_level){display(datatwo);} total=0; dataa=split(dataone,sep:" "); datab=split(datatwo,sep:" "); ta=max_index(dataa)-1; tb=max_index(datab)-1; totallength=ta+tb; foreach one (dataa){ foreach two (datab){ if (one == two ){ if (debug_level){display ("match:"+one+"\r\n");} total++; } } } if (debug_level){display("total length is:"+totallength+"\r\n");} if (debug_level){display("total is:"+total+"\r\n");} return(200*total/totallength); } # ------------------------------------------------------------# function http_convertURL2directory(URL){ local_var callpieces,dirpieces,location,piece,i; # look for boundaries # We want to do # callpieces=split(URL,sep:"#,?,!,$,^,&,\\,*,\,"); # but it seems we cant..that sucks a bit.. callpieces=split(URL,sep:'?'); dirpieces=split(callpieces[0],sep:"/"); location=""; for (i=0; i0){ location=location+piece; } } return location; } # ------------------------------------------------------------# function http_convertURL2extention(URL){ local_var callpieces,dirpieces,extpieces,location,piece,ext; # look for boundaries callpieces=split(URL,sep:"?"); dirpieces=split(callpieces[0],sep:"/"); extpieces=split(dirpieces[max_index(dirpieces)-1], sep:"."); ext=extpieces[max_index(extpieces)-1]; ext=ereg_replace(string:ext,pattern:"\?",replace:""); if (strlen(ext) > 5){ return "default"; } else return (ext); }