# this looks for php based exploits, parses out the download address and looks # for connections to them. # written by Scott Campbell # @load http module PHP_TEST; export { const PHP_PATH_URI = /root_path/ | /include_path/ | /sl_theme_unix_path/&redef; const address_pat = /[0-9,\.]{7,15}/; global notify_on_detect = T; global hostile_uri_address: table[addr] of string; global hostile_source_address: set[addr]; } redef enum Notice += { URI_ConnectBack, Hostile_URI, }; function add_address(a: addr, uri: string) { if ( a !in hostile_uri_address ) { hostile_uri_address[a] = uri; } } function test_address(c: connection) { local id = c$id; local inbound = is_local_addr(id$resp_h); if ( !inbound && ( id$resp_h in hostile_uri_address ) ) { NOTICE([$note=URI_ConnectBack, $src=id$orig_h, $msg = fmt("to %s from %s via %s", id$resp_h, id$orig_h, hostile_uri_address[id$resp_h])]); } } function process_uri(uri: string) { # first extract the hostname from the uri. we assume the form # hostname/data/data ... # if the data is not there this ought to work as well (?) local host_set = split(uri, /\//); local host = host_set[1]; local host_test = fmt("X%s", host); if ( host_test == "X" ) return; # now look up the hostname if it looks like a non-ip if ( address_pat !in host) { when ( local trans_address = lookup_hostname(host) ) { local a:addr; for ( a in trans_address ) { #print fmt("looking at %s %s", host, a); add_address(a, uri); } } timeout 10 sec { #print "no lookup"; } } else add_address(to_addr(host),uri); } event http_request(c: connection, method: string, original_URI: string, unescaped_URI: string, version: string) { local URI = unescaped_URI; if ( PHP_PATH_URI in URI ) { if ( notify_on_detect && c$id$orig_h !in hostile_source_address ) { NOTICE([$note=Hostile_URI, $src=c$id$orig_h, $msg = fmt(" %s -> %s %s", c$id$orig_h, c$id$resp_h, URI)]); add hostile_source_address[c$id$orig_h]; } local embedded_uri = split(URI, /http:\/\//); local num_embedded_uri = length(embedded_uri); local i = 2; if ( num_embedded_uri < 1 ) return; # while it is not all that uncommon to have more than one # name in the attack uri, we are looking for indications that # the attack was successful process_uri(embedded_uri[2]); } } event connection_attempt(c: connection) { test_address(c); } event connection_rejected(c: connection) { test_address(c); } event connection_reset(c: connection) { test_address(c); } event connection_established(c: connection) { test_address(c); }