# # written by Jon Passki - Shavlik Technologies, LLC # This script is Copyright (C) 2005 Shavlik Technologies, LLC # BIG-IP(R) is a registered trademark of F5 Networks, Inc. # F5 BIP-IP Cookie Persistence Decoder # # if(description) { script_id(99999); script_version ("$Revision: 1.0 $"); name["english"] = "F5 BIP-IP Cookie Persistence Decoder"; script_name(english:name["english"]); desc["english"] = " The F5 BigIP load balancer encodes within a cookie the IP address of the actual web server it is acting on behalf of. This value may disclosure sensitive information, such as internal IP addresses. BIG-IP(R) is a registered trademark of F5 Networks, Inc. Solution: http://www.f5.com/solutions/archives/techbriefs/cookie.html Risk factor : Low"; script_description(english:desc["english"]); summary["english"] = "F5 BIP-IP(R) Cookie Persistence Decoder"; script_summary(english:summary["english"]); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 2005 Shavlik Technologies, LLC"); family["english"] = "Web servers"; script_family(english:family["english"]); script_require_ports("Services/www", 80); exit(0); } # # Start # function cookie_cutter(ugly, count) { local_var crumbles,i,pieces,top,bottom; crumbles = ugly; pieces = split(crumbles, sep:"=", keep:0); crumbles = split(pieces[1], sep:".",keep:0); for (i=0;i<=count;i++) pieces[i+1] = crumbles[i]; # Hack to convert a string that represents a value greater than 2^31 -1 # Look away! if (strlen(pieces[1]) > 9) { bottom = int( substr(pieces[1],5) ); top = int( substr(pieces[1],0,4) ); pieces[1] = top * 10**5 + bottom; } return pieces; } function cookie_conv(ugly, count) { local_var BIGIP; BIGIP = ugly; for (i=0;i<=count;i++) internal_ip[i] = ( BIGIP >> i*8 ) & 0x000000FF; return internal_ip; } function showme(pretty, type) { local_var ip_str,i,j; foreach i (pretty) ip_str = string(ip_str,i, "."); if(type == "ip") return ereg_replace(string:ip_str, pattern:"\.$", replace:""); else if(type == "port") return string(int(ereg_replace(string:ip_str, pattern:"\.", replace:""))); } # # The script code starts here # include("http_func.inc"); port = get_http_port(default:80); if(get_port_state(port)) { # Default number of HTTP connections # Gets reset if a new cookie is found, so this is not bounded # Which shouldn't be an issue, unless you're dealing with the mother # of all load balanced sites. retries = 5; array_index = -1; not_yummy = 0; good_results = 0; while(retries) { soc = http_open_socket(port); if(! soc) { report_error = 1; break; } req = http_get(item:"/", port:port); send(socket:soc, data:req); http_headers = http_recv_headers(soc); http_close_socket(soc); # Don't use ereg, since there might be more than one cookie set # We risk having false negatives since the cookie values might not # have the BIGip part. I think I recall seeing 'oreo' once that # had a value similar to the BIG-IP cookies. # Also to note, if this cookie is replayed in subsequent requests, # the load balancer will have an affinity with the back end. # This might be a good knowledge base entry. cookie = egrep(string:http_headers, pattern:"^.*Cookie:.*BIGipServer.*=.*"); if(! cookie) { report_error = 2; break; } cookie = eregmatch(string:cookie, pattern:"BIGipServer([^; ])+" ); for(i=0;i<=array_index;i++) if(cookie_jar[i] == cookie[0]) not_yummy = 1; if(! not_yummy) { cookie_jar[++array_index] = cookie[0]; whoops = cookie_cutter(ugly:cookie[0], count:2); #XXX cookie_conv and showme should be merged converted[0] = cookie_conv(ugly:whoops[1], count:3); converted[1] = cookie_conv(ugly:whoops[2], count:1); converted[2] = cookie_conv(ugly:whoops[3], count:1); src_http[0] = showme(pretty:converted[0], type:"ip"); src_http[1] = showme(pretty:converted[1], type:"port"); ip_jar[array_index] = src_http; good_results = 1; retries = 3; } else retries--; not_yummy = 0; } # while(retries) if(good_results) { if(report_error == 1) report = " The script failed in making a socket connection to the target system after a previous connection worked. This may affect the completeness of the report and you might wish to rerun this test again on the targeted system. "; if(report_error == 2) report = " The script failed in finding a BIG-IP cookie on the target system after a previous cookie was found. This may affect the completeness of the report and you might wish to rerun this test again on the targeted system. "; report = report + " The F5 BIG-IP load balancer encoded within a cookie the IP address and TCP port of the load balanced web server. Additionally, information after 'BIGipServer' is configured by the user and may be the logical name of the device. These values may disclose sensitive information, such as internal IP addresses and names. BIG-IP(R) is a registered trademark of F5 Networks, Inc. The first column is the original cookie, the second the IP address and the third the TCP port: "; for(i=0;i<=array_index;i++) { big_ip = ip_jar[i]; report = report + " " + cookie_jar[i] + " " + big_ip[0] + " " + big_ip[1] ; } if (strlen(report)) security_warning(port:port, data:report); } #good_results exit(0); } #if(get_port_state(port))