Hi, I have coded up the change I suggested to stop these plugins causing false positives when the XSS url appears in the response headers. I've added a bodyonly option to http_keepalive_send_recv, and modified the plugins to use this function. I've tested them against a simple CGI scripts that's vulnerable to all XSS and they work fine, but I don't have vulnerable hosts to test against. And I did check keepalive operation when keepalives disabled - works fine. Best wishes, Paul -- Paul Johnston Internet Security Specialist Westpoint Limited Albion Wharf, 19 Albion Street, Manchester, M1 5LN England Tel: +44 (0)161 237 1028 Fax: +44 (0)161 237 1031 email: paulat_private web: www.westpoint.ltd.uk # -*- Fundamental -*- # http_keepalive.inc # (C) Renaud Deraison # $Id: http_keepalive.inc,v 1.17 2003/06/05 14:08:26 renaud Exp $ # # # The only function which should be used by an external plugin is # http_keepalive_send_recv(port, data) which returns the result # (or NULL if no connection could be established). # # Note that the file "http_func.inc" must also be included when # using this file. # __ka_socket = 0; __ka_port = 0; __ka_enabled = -1; __ka_last_request = ""; # # Based on the last headers we received, we determine if we need # to close our socket and re-open it or not # function http_keepalive_check_connection(headers) { tmp = egrep(pattern:"^Connection: [Cc]lose", string:headers); if(tmp) { http_close_socket(__ka_socket); __ka_socket = http_open_socket(__ka_port); } } function enable_keepalive(port) { __ka_enabled = 1; __ka_port = port; __ka_socket = http_open_socket(port); } # # This function determines if the remote web server is # keep-alive-enabled or not. # function http_keepalive_enabled(port) { local_var req, soc, r, kb; kb = get_kb_item(string("www/", port, "/keepalive")); if(kb == "yes"){ enable_keepalive(port:port); return(1); } else if(kb == "no")return(0); req = string("GET / HTTP/1.1\r\n", "Connection: Keep-Alive\r\n", "Host: ", get_host_name(), "\r\n", "Pragma: no-cache\r\n", "User-Agent: Mozilla/4.75 [en] (X11, U; Nessus)\r\n\r\n"); soc = http_open_socket(port); if(!soc)return NULL; send(socket:soc, data:req); r = http_recv(socket:soc); # Apache if(egrep(pattern:"^Keep-Alive:.*", string:r)) { http_close_socket(soc); set_kb_item(name:string("www/", port, "/keepalive"), value:"yes"); enable_keepalive(port:port); return(1); } else { # IIS send(socket:soc, data:req); r = http_recv(socket:soc); http_close_socket(soc); if(strlen(r)){ set_kb_item(name:string("www/", port, "/keepalive"), value:"yes"); enable_keepalive(port:port); return(1); } } set_kb_item(name:string("www/", port, "/keepalive"), value:"no"); return(0); } # # This function is akin to http_recv() except that if the last request # was a HEAD, we bail out (whereas http_recv() will timeout). # function http_keepalive_recv(bodyonly) { local_var headers, body, length, tmp, chunked, killme; killme = 0; length = -1; headers = http_recv_headers(__ka_socket); if(strlen(headers) == 0)headers = http_recv_headers(__ka_socket); if(ereg(pattern:"^HEAD.*HTTP/.*", string:__ka_last_request)) { # HEAD does not return a body http_keepalive_check_connection(headers:headers); if(bodyonly) return(""); else return(headers); } if("Content-Length" >< headers) { tmp = egrep(string:headers, pattern:"^Content-Length: [0-9]*"); length = int(ereg_replace(string:tmp, pattern:"^Content-Length: ([0-9]*)", replace:"\1")); } if((length < 0) && (egrep(pattern:"transfer-encoding: chunked", string:headers, icase:TRUE))) { while(1) { tmp = recv_line(socket:__ka_socket, length:4096); length = hex2dec(xvalue:tmp); if(length > 1024*1024*10) { length = 1024*1024; killme = 1; } body = string(body, recv(socket:__ka_socket, length:length+2, min:length+2)); if(strlen(body) > 1024*1024*10)killme = 1; if(length == 0 || killme){ http_keepalive_check_connection(headers:headers); # This is expected - don't put this line before the previous if(bodyonly) return(body); else return(string(headers,"\r\n", body)); } } } if(length >= 0) { # Don't receive more than 10MB if(length > 1024*1024*10)length = 1024*1024; body = recv(socket:__ka_socket, length:length, min:length); } else { # If we don't have the length, we close the connection to make sure # the next request won't mix up the replies. #display("ERROR - Keep Alive, but no length!!!\n", __ka_last_request); body = recv(socket:__ka_socket, length:16384); http_close_socket(__ka_socket); __ka_socket = http_open_socket(__ka_port); } http_keepalive_check_connection(headers:headers); if(bodyonly) return(body); else return(string(headers,"\r\n", body)); } #----------------------------------------------------------------------# # We close our socket on exit. function on_exit() { if(__ka_socket) { http_close_socket(__ka_socket); } } #----------------------------------------------------------------------# # # This is our "public" Keep-Alive function. It sends <data> to the remote # host on port <port>, and returns the result, or NULL if no connection # could be established. # function http_keepalive_send_recv(port, data, bodyonly) { local_var id, n; if(__ka_enabled == -1)__ka_enabled = http_keepalive_enabled(port:port); if(__ka_enabled == 0) { local_var soc, r; soc = http_open_socket(port); if(!soc)return NULL; send(socket:soc, data:data); headers = http_recv_headers(soc); if(headers) body = http_recv_body(socket:soc, headers:headers, length:0); http_close_socket(soc); if(bodyonly) return(body); else return(string(headers, "\r\n", body)); } if((port != __ka_port)||(!__ka_socket)) { if(__ka_socket)http_close_socket(__ka_socket); __ka_port = port; __ka_socket = http_open_socket(port); if(!__ka_socket)return NULL; } id = stridx(data, string("\r\n\r\n")); data = str_replace(string:data, find:"Connection: Close", replace:"Connection: Keep-Alive", count:1); __ka_last_request = data; n = send(socket:__ka_socket, data:data); if(n <= 0) { http_close_socket(__ka_socket); __ka_socket = http_open_socket(__ka_port); if(__ka_socket == 0)return NULL; send(socket:__ka_socket, data:data); } return(http_keepalive_recv(bodyonly:bodyonly)); } # # Same as check_win_dir_trav(), but with KA support # function check_win_dir_trav_ka(port, url, quickcheck) { local_var soc, req, cod, buf; #display("check_win_dir_trav(port=", port, ", url=", url, ", quickcheck=", quickcheck, ")\n"); req = http_get(item:url, port:port); buf = http_keepalive_send_recv(port:port, data:req); if (quickcheck) { if (ereg(pattern:"^HTTP/.* 200 ", string:buf)) return (1); return (0); } if ( ("ECHO" >< buf) || ("SET " >< buf) || ("export" >< buf) || ("EXPORT" >< buf) || ("mode" >< buf) || ("MODE" >< buf) || ("doskey" >< buf) || ("DOSKEY" >< buf) || ("[boot loader]" >< buf) || ("[fonts]" >< buf) || ("[extensions]" >< buf) || ("[mci extensions]" >< buf) || ("[files]" >< buf) || ("[Mail]" >< buf) || ("[operating systems]" >< buf) ) { return(1); } return(0); } # # # function is_cgi_installed_ka(item, port) { local_var r, no404, dir; if(item[0] != "/") { dir = cgibin(); item = string(dir, "/", item); } r = http_keepalive_send_recv(port:port, data:http_get(item:item, port:port)); if( r == NULL ) return NULL; no404 = get_kb_item(string("www/no404/", port)); if(ereg(pattern:"^HTTP.* 200 .*", string:r)) { if(no404) { if(tolower(no404) >< tolower(r))return(0); } return(1); } return(0); } # # This script was written by Geoffroy Raimbault <graimbault@lynx-technologies.com> # # www.lynx-technologies.com # # See the Nessus Scripts License for details # if(description) { script_version ("$Revision: 1.4 $"); script_id(11142); script_bugtraq_id(5900); name["english"] = "IIS XSS via error"; name["francais"] = "IIS XSS via une erreur IDC"; script_name(english:name["english"], francais:name["francais"]); desc["english"] = " This IIS Server appears to be vulnerable to a Cross Site Scripting due to an error in the handling of overlong requests on an idc file. It is possible to inject Javascript in the URL, that will appear in the resulting page. Risk factor : Medium See also : http://online.securityfocus.com/bid/5900 http://www.ntbugtraq.com/default.asp?pid=36&sid=1&A2=ind0210&L=ntbugtraq&F=P&S=&P=1391 "; script_description(english:desc["english"]); summary["english"] = "Tests for IIS XSS via IDC errors"; summary["francais"] = "Test de la vulnérabilité XSS dans IIS via une erreur IDC"; script_summary(english:summary["english"], francais:summary["francais"]); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 2002 Geoffroy Raimbault/Lynx Technologies", francais:"Ce script est Copyright (C) 2002 Geoffroy Raimbault/Lynx Technologies"); family["english"] = "CGI abuses"; family["francais"] = "Abus de CGI"; script_family(english:family["english"], francais:family["francais"]); script_dependencie("find_service.nes", "no404.nasl","http_version.nasl"); script_require_ports("Services/www", 80); script_require_keys("www/iis"); exit(0); } include("http_func.inc"); include("http_keepalive.inc"); port = get_kb_item("Services/www"); if(!port)port = 80; if(get_port_state(port)) { # We construct the malicious URL with an overlong idc filename filename = string("/<script></script>",crap(334),".idc"); req = http_get(item:filename, port:port); r = http_keepalive_send_recv(port:port, data:req, bodyonly:1); str="<script></script>"; if((str >< r)) security_warning(port); } # # This script was written by Renaud Deraison <deraisonat_private> # # See the Nessus Scripts License for details # if(description) { script_id(11395); script_version ("$Revision: 1.1 $"); script_cve_id("CAN-2000-0746"); script_bugtraq_id(1594, 1595); name["english"] = "Microsoft Frontpage XSS"; script_name(english:name["english"]); desc["english"] = " The remote server is vulnerable to Cross-Site-Scripting (XSS) when the FrontPage CGI /_vti_bin/shtml.dll is fed with improper arguments. Solution : See http://www.microsoft.com/technet/security/bulletin/ms00-060.asp Risk factor : Medium"; script_description(english:desc["english"]); summary["english"] = "Checks for the presence of a Frontpage XSS"; script_summary(english:summary["english"]); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 2003 Renaud Deraison", francais:"Ce script est Copyright (C) 2003 Renaud Deraison"); family["english"] = "CGI abuses"; family["francais"] = "Abus de CGI"; script_family(english:family["english"], francais:family["francais"]); script_dependencie("find_service.nes", "no404.nasl", "http_version.nasl"); script_require_ports("Services/www", 80); script_require_keys("www/iis"); exit(0); } # # The script code starts here # include("http_func.inc"); include("http_keepalive.inc"); port = get_kb_item("Services/www"); if(!port)port = 80; if(!get_port_state(port))exit(0); req = http_get(item:"/_vti_bin/shtml.exe/<script>alert(document.domain)</script>", port:port); res = http_keepalive_send_recv(port:port, data:req, bodyonly:1); if( res == NULL ) exit(0); if("<script>alert(document.domain)</script>" >< res)security_warning(port); # # This script was written by Renaud Deraison <deraisonat_private> # # Script audit and contributions from Carmichael Security <http://www.carmichaelsecurity.com> # Erik Anderson <eandersat_private> # Added links to the Bugtraq message archive and Microsoft Knowledgebase # # See the Nessus Scripts License for details # if(description) { script_id(10844); script_version ("$Revision: 1.6 $"); name["english"] = "ASP.NET Cross Site Scripting"; script_name(english:name["english"]); desc["english"] = " ASP.NET is vulnerable to a cross site scripting vulnerability. Solution : There was no solution ready when this vulnerability was written; Please contact the vendor for updates that address this vulnerability. Reference : http://online.securityfocus.com/archive/1/254001 Reference : http://msdn.microsoft.com/library/en-us/dncode/html/secure07152002.asp Risk factor : Medium"; script_description(english:desc["english"]); summary["english"] = "Tests for ASP.NET CSS"; script_summary(english:summary["english"]); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 2002 Renaud Deraison", francais:"Ce script est Copyright (C) 2002 Renaud Deraison"); family["english"] = "CGI abuses"; family["francais"] = "Abus de CGI"; script_family(english:family["english"], francais:family["francais"]); script_dependencie("find_service.nes", "no404.nasl", "http_version.nasl"); script_require_ports("Services/www", 80); script_require_keys("www/iis"); exit(0); } include("http_func.inc"); include("http_keepalive.inc"); port = get_kb_item("Services/www"); if(!port)port = 80; if(get_port_state(port)) { str = "/~/<script>alert(document.cookie)</script>.aspx?aspxerrorpath=null"; req= http_get(item:str, port:port); soc = http_open_socket(port); if(soc) { r = http_keepalive_send_recv(port:port, data:req, bodyonly:1); lookfor = "<script>alert(document.cookie)</script>"; if(lookfor >< r) { security_warning(port); } } }
This archive was generated by hypermail 2b30 : Fri Sep 12 2003 - 06:49:06 PDT