< Previous Page Return to Title Page Next Page >

A cute (but effective) hack: An Apache IDS in zero lines of code

  • A  primitive IDS can be implemented directly within Apache using the built-in regex matching and conditional logging. The SetEnvIf and LogFormat directives can send formatted lines of data to an external program in response to specific events. If that external program is a privileged shell (or an invocation of SSH that opens a privileged shell on your firewall router), Apache can administer the system or network when it "thinks" it's merely logging an access. For example:

  •  
    # Flag requests for URIs containing common strings from Nimda-like worms 
    # (including Code Red, sadmind/IIS). Note that the patterns below are regexes;
    # remember to escape dots and other characters with special significance!
    
    SetEnvIf Request_URI "/winnt/system32/cmd\.exe" worm
    SetEnvIf Request_URI "/scripts/root\.exe" worm
    SetEnvIf Request_URI "/MSADC/root\.exe" worm
    # Don't use the following patterns if you use "upreferences" in links
    # on your Web pages
    SetEnvIf Request_URI "/\.\." worm
    SetEnvIf Request_URI "\.\./" worm
    # Block attackers who send the patterns above within URIs. The command below
    # uses a blackhole route. It's more efficient to firewall (the command
    # will vary depending upon the firewall in use) or to use SSH to add rules to
    # an upstream firewall to block the attacker, but this method has the
    # advantage that it is relatively independent of configuration. If several 
    # commands must be executed, or if postprocessing of output is desired, it
    # is best to invoke a script or compiled program rather than doing all the 
    # work from within httpd.conf.
    
    CustomLog "|/bin/sh" "route -nq add -host %a 127.0.0.1 -blackhole" env=worm
    # Note that no input from the client shows up in the shell command, so this
    # set of directives is not subject to exploits via crafted strings. If strings
    # from the client had a way of getting to the root shell, very strong input
    # validation would be in order.
  • Unfortunately, what one can do within httpd.conf is very limited. So, it often pays to write an independent application that can fully parse the log, gather statistics, and take action when certain conditions are spotted.