# $Id: http-request.bro,v 1.14 2003/08/31 00:40:21 vern Exp $

# Analysis of HTTP requests.

@load http

redef capture_filters +=  {
	["http-request"] = "tcp dst port 80 or tcp dst port 8080 or tcp dst port 8000"
};

const sensitive_URIs =
	  /etc.*\/.*(passwd|shadow|netconfig)/
	| /IFS[ \t]*=/
	| /nph-test-cgi\?/
	| /(%0a|\.\.)\/(bin|etc|usr|tmp)/
	| /[iI][iI][sS][aA][dD][mM][pP][wW][dD]/
	| /\/(cmd|root|tftp)\.exe/
	| /\/Admin_files\/order\.log/
	| /\/carbo\.dll/
	| /\/cgi-bin\/(phf|php\.cgi|test-cgi)/
	| /\/cgi-dos\/args\.bat/
	| /\/cgi-win\/uploader\.exe/
	| /\/search97\.vts/
	&redef;

# URIs that match sensitive_URIs but can be generated by worms, and hence
# should not be flagged (because they're so common).
const worm_URIs =
	  /.*\/c\+dir/
	| /.*cool.dll.*/
	| /.*Admin.dll.*Admin.dll.*/
	&redef;

# URIs that should not be considered sensitive if accessed remotely,
# i.e. by a local client.
const skip_remote_sensitive_URIs: pattern &redef;
# In order to redef skip_remote_sensitive_URIs, you have to also
# redef the following to T, because there's currently no way in Bro
# to specify an empty pattern that can otherwise be used as the default
# for skip_remote_sensitive_URIs.
const have_skip_remote_sensitive_URIs = F &redef;

const sensitive_post_URIs = /wwwroot/ &redef;

event http_request(c: connection, method: string, original_URI: string, 
			unescaped_URI: string, version: string)
	{
	local log_it = F;
	local URI = unescaped_URI;

	if ( (sensitive_URIs in URI && URI != worm_URIs) ||
	     (method == "POST" && sensitive_post_URIs in URI) )
		{
		if ( have_skip_remote_sensitive_URIs &&
		     is_local_addr(c$id$orig_h) &&
		     skip_remote_sensitive_URIs in URI )
			; # don't flag it after all
		else
			log_it = T;
		}

	local s = lookup_http_request_stream(c);

	if ( process_HTTP_replies )
		{
		# To process HTTP replies, we need to record the corresponding
		# requests.
		local n = s$first_pending_request + s$num_pending_requests;

		s$requests[n] = [$method=method, $URI=URI, $log_it=log_it];
		++s$num_pending_requests;

		# if process_HTTP_messages
		local msg = s$next_request;

		init_http_message(msg);
		msg$initiated = T;
		}
	else
		{
		if ( log_it )
			ALERT([$alert=HTTP_SensitiveURI, $conn=c,
				$msg=fmt("%s %s: %s %s",
					id_string(c$id), c$addl, method, URI)]);
		print http_log,
			fmt("%.6f %s %s %s", network_time(), s$id, method, URI);
		}
	}
