7

My web server (apache2) is continually pounded by malicious bots, asking for URLs like these:

   /blog/tag/pnphpbb2//index.php?name=PNphpBB2&file=posting&mode=quote/index.php?name=PNphpBB2&file=viewtopic&p=34004/viewtopic.php?p=15&sid=be4c914eb746ac7c96beea717fdfc692/&highlight=../../../../../../../../../../../../../etc/passwd%00 HTTP Response 301

   //index.php?name=PNphpBB2&file=posting&mode=quote/index.php?name=PNphpBB2&file=viewtopic&p=34004/viewtopic.php?p=15&sid=be4c914eb746ac7c96beea717fdfc692/&highlight=../../../../../../../../../../../../../etc/passwd%00 HTTP Response 200

   /wiki/index.php/Main:Some_Wiki_Pagename//index.php?name=PNphpBB2&file=posting&mode=quote/index.php?name=PNphpBB2&file=viewtopic&p=34004/viewtopic.php?p=15&sid=be4c914eb746ac7c96beea717fdfc692/&highlight=../../../../../../../../../../../../../etc/passwd%00 HTTP Response 200

   /wiki/index.php//index.php?name=PNphpBB2&file=posting&mode=quote/index.php?name=PNphpBB2&file=viewtopic&p=34004/viewtopic.php?p=15&sid=be4c914eb746ac7c96beea717fdfc692/&highlight=../../../../../../../../../../../../../etc/passwd%00 HTTP Response 200

   /blog/2009/01/title-of-post-here//index.php?name=PNphpBB2&file=posting&mode=quote/index.php?name=PNphpBB2&file=viewtopic&p=34004/viewtopic.php?p=15&sid=be4c914eb746ac7c96beea717fdfc692/&highlight=../../../../../../../../../../../../../etc/passwd%00 HTTP Response 301

I'd like a nightly cron process to find any host requesting a "malicious" URL, and add them to an HTTP equivalent to hosts.deny.

I would imagine that there would be a set of regexps defining malicious URLs, and well as possibly some apache plugin to easily do the host denying (without having to do an httpd restart every night).

Does anything like this exist?

slacy
  • 930
  • 1
  • 9
  • 11
  • And no, I don't have a PNphpBB installation, and I've checked that these aren't legitimate security holes in my server. – slacy Jun 05 '09 at 17:31
  • See also http://denyhosts.sourceforge.net/ – slacy Jun 05 '09 at 17:31
  • It looks like two of these "malicious" URLs worked (response code 200). – David Jun 05 '09 at 19:41
  • Wouldn't this open you up to a nasty denial of service attack? If I access a URL on your ban list, anybody else using the same proxy as me now can't reach your site. – David Schwartz Oct 27 '11 at 09:32
  • @David: The 200 just means he gave them back a page. It's most likely an error page (though not an HTTP error) that says the request could not be understood or the like. (Because he's not running versions of those scripts that are vulnerable, but the scripts exist.) – David Schwartz Oct 27 '11 at 09:33
  • @DavidSchwartz Yeah, I double checked that what looks like a success (200) is actually an error page. I didn't hand out /etc/passwd. :) – slacy Oct 27 '11 at 16:42

7 Answers7

7

http://www.modsecurity.org/ may do what you want.

David Pashley
  • 23,497
  • 2
  • 46
  • 73
7

fail2ban scans log files like /var/log/apache/error_log and bans IP that makes these automated scans based on regular expressions (called filters). By default it updates the firewall (iptables) to block the offending IP. It is very easy to write new actions and implementing one for updating a .htaccess should be quite simple, there are several examples available in the fail2ban distribution.

rkthkr
  • 8,618
  • 28
  • 38
1

I'll second fail2ban. It works live, it can ban temporarily, and it can add IP addresses to your firewall so Apache doesn't have to waste time on it.

Even more efficient when coupled with the ipset netfilter module for iptables (which is faster for handling large amounts of addresses), and it can ban them instantly so they only get to make one or two requests before getting blocked.

If you really, really hate these people and are running Linux, you could also try to implement tarpitting for iptables (a quick search hasn't found any 2.6-compatible patches). This will accept the connection and then immediately set the window size to 0 (preventing data from being transferred), but also prevent the remote end from closing the connection at all, meaning whatever app is connecting will have to wait somewhere between three and twenty (!!) minutes before the connection times out on their end.

This is great for stopping portscanners as well, because it makes them take orders of magnitude longer than they normally would.

Dan Udey
  • 1,468
  • 12
  • 17
0

If it's Apache 2.0, you can try mod_access: http://httpd.apache.org/docs/2.0/mod/mod_access.html

In Apache 2.2, it's mod_authz_host: http://httpd.apache.org/docs/2.2/mod/mod_authz_host.html

It sure looks like you're going to have to signal Apache to reload its configuration to make changes in the module's configuration take effect, though.

Edit: Modsecurity looks like what you want, as opposed to building static deny configurations by grepping your log files and using one of the above. I'm gonna upvote that answer now.

Evan Anderson
  • 141,881
  • 20
  • 196
  • 331
  • Yes, it looks like mod_acess would allow me to manually deny access to these users, but I'm looking for something that automatically bans any IP address that's attempting to request a URL that matches a given set of regexps. In other words, if the URL matches ".*/etc/passwd.*" then permanently (and immediately) ban the requester. I guess I could create some manual URL rules for this myself and try them out, but I was hoping for something well maintained... – slacy Jun 05 '09 at 17:30
0

Another possibility is using mod_rewite to match the URL and sending the client a 403 (or whatever code you want). Example:

RewriteEngine on
RewriteRule ^/.*passwd.*/ - [L,NC,G]

Or for fun:

RewriteEngine on
RewriteRule ^/(.*passwd.*)/ http://127.0.0.1/$1 [L,NC,R=301]
David
  • 3,555
  • 22
  • 17
  • Regular expressions are pretty heavy, and executing them for every request is sub-optimal. Doing it just to redirect someone or block an IP address is inefficient. If nothing else, a 'Deny from' rule in a block is more efficient. – Dan Udey Jun 05 '09 at 22:12
0

I would certainly look at OSSEC. It detects these patterns and can block the ip addresses. It also looks for scans (multiple 404s for example) and block the offender IP.

And yes, it does that by default.

Link: http://www.ossec.net

sucuri
  • 2,867
  • 1
  • 23
  • 22
-1

An example would be:

<Location />
   Order Deny,Allow
   Deny from 123.123.123.123 231.213.123.0/24
   Allow from all
</location>

I'd recommend having this in a separate file that you include from your main config and just rewrite this small fragment. You can do a reload to pick up the change, which doesn't stop your server like a restart would.

David Pashley
  • 23,497
  • 2
  • 46
  • 73
  • 1
    Yes, that's how to deny access, but I'm looking for something that detects bad behavior based on URL access patterns, and then denies specific IP addresses (or ranges) based on that. – slacy Jun 05 '09 at 17:32