Redirecting Script Kiddies With Apache 2016-04-09
I imagine that a lot of web site owners don't really pay much attention to their logs, and are not really interested in knowing about the spammers, infected computers, and script kiddies who are likely accessing their site. If you are reading this, you are probably not one of those people. If you run apache, hopefully this information will help you to deflect some of their attacks, keep your logs a little cleaner, and generally make you feel better about your site's security.
One of the first tips I can offer is to not run Wordpress. It is clearly very popular for a number of reasons, but it is also very frequently attacked. In fact, Wordpress itself isn't likely to be the problem, the endless parade of plugins are much more likely to be the target of attacks aimed at you. This is because plugins are typically not subjected to the same rigorous testing that Wordpress itself is. I would go on to say that it is a good idea to avoid running any popular site generating software if you can avoid it. This means all kinds of things like Joomla, Drupal, Dokuwiki, and a parade of other "apps" that refer to themselves as Content Management Systems. I realize that creating and maintaining a site that is not built on a platform like these can be a pain, and is beyond the abilities or interest of many people, but if you are able to avoid them you'll essentially be getting rid of a whole pile of related possible security issues. That is not to say that a homebrew site is entirely secure, it just means that you are not dragging a whole pile of code that you didn't write, in to your site.
Having said all that, if you run Apache (I happen to run v2.2 here) then you can use mod_rewrite to redirect annoyances to other locations which might be local to you or external. You might wish to redirect them to a tarpit or honeypot that you control, and these may be used in turn to automatically block them from accessing other parts of your network. I recently started just redirecting them back at themselves in hopes that someone may see the entries in their log files and fix the problem. What I mean is that many times the attack on your web server is not coming from a kid with greenish skin in his mom's basement drinking Dr. Pepper and eating pizza... in many cases it is simply someone else's web site that is already infected. If I redirect the requests back at their webserver then the malware will hopefully follow the redirection, the admin will see it in their logs (wishful thinking), and they'll go get rid of the virus.
For example, since I am not running Wordpress at snork.ca anymore, I can safely say that nobody should ever be accessing the Wordpress login page here. So I can create a rule that will redirect anyone accessing wp-login.php to a destination of my choice. Now this can be done using a .htaccess file, but since I run the web server here I prefer to put the rules right in to my Apache httpd.conf file. The idea is the same, and it accomplishes the same goal, but if you are using a web hosting provider of some kind you will likely be restricted to using an .htaccess file. Here's what my example looks like:
RewriteRule ^/wp-login\.php$ http://%{REMOTE_ADDR}/NOTICE-%{REMOTE_ADDR}-IS-INFECTED-OR-HACKING.html [R,L]
Let's chop that in to pieces to make sense on the individual parts.
- RewriteRule means "This is a Rewrite Rule" and is the directive that tells Apache to rewrite the URL.
- ^/wp-login\.php$ means "when the URL is exactly /wp-login.php". The ^ marks the beginning of the URL and $ marks the end of it. So this will only match /wp-login.php and not /wordpress/wp-login.php or /wp-login.php4 or /wp-login.html. You do not have to include the ^ and $ on each rule, but if you can be more specific by using them it will help to avoid unintentionally redirecting legitimate browser activity. Notice of course that the . (dot) in the filename has to be escaped in these rules.
- http://%{REMOTE_ADDR}/NOTICE-%{REMOTE_ADDR}-IS-INFECTED-OR-HACKING.html is where the request will be redirected to. The %{REMOTE_ADDR} part is an Apache server variable and is the IP address that is making the request.
- [R,L] are the Rewrite Flags which tell Apache to Rewrite the whole URL and that if this rule applies, then it is the Last rule to process.
So let's say for the sake of example that the IP address 136.243.145.81 tries to access my web site at https://snork.ca/wp-login.php. If you click on the whois link you'll see it is a Hetzner owned IP address in Germany, and if you click on the IP address itself you'll see (today at least) that it is a web server running Debian and showing the default Apache page. My Spidey Senses™ tell me that this web server is probably infected with some virus that is attacking my web server.
The above rule will redirect this request to http://136.243.145.81/NOTICE-136.243.145.81-IS-INFECTED-OR-HACKING.html. This means that if the owner of that web site checks her logs she'll see an entry like this
136.243.145.81 - - [09/Apr/2016:03:19:58 -0400] "GET /NOTICE-136.243.145.81-IS-INFECTED-OR-HACKING.html HTTP/1.1" 404 378 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
Now it is entirely possible that the administrator of that site will never see the log entry, and just as possible that the virus won't even follow the redirect, but it makes me feel warm and fuzzy to know that at least my Apache just sent them back and ignored the request. So here are a few more examples for you to play with
This will redirect when someone tries to access anything in your "/cgi-bin" directory.
RewriteRule ^/cgi-bin/ http://%{REMOTE_ADDR}/NOTICE-%{REMOTE_ADDR}-IS-INFECTED-OR-HACKING.html [R,L]
This will redirect when the URL ends in ".libs.php".
RewriteRule \.libs\.php$ http://%{REMOTE_ADDR}/NOTICE-%{REMOTE_ADDR}-IS-INFECTED-OR-HACKING.html [R,L]
This is the same as the last rule except that it also adds a "donotlog" environment variable. This can be used for conditional logging where you either force the log entry to a separate log file, or drop the log entry altogether.
RewriteRule \.libs\.php$ http://%{REMOTE_ADDR}/NOTICE-%{REMOTE_ADDR}-IS-INFECTED-OR-HACKING.html [R,L,E=donotlog]
Using a Rewrite Condition you can also redirect based on things like the query string. This takes two or more lines in your config file.
RewriteCond %{QUERY_STRING} ^p=741$
RewriteRule / http://%{REMOTE_ADDR}/NOTICE-%{REMOTE_ADDR}-IS-INFECTED-OR-HACKING.html [R,L]
This three line example uses Rewrite Conditions to only redirect when the referrer is "semalt.com" and the user-agent is "the beast". Both must be true for this rule to fire, and the [NC} means that case does not matter, so "ThE BeaST" would also fire the rule.
RewriteCond %{HTTP_REFERER} semalt.com [NC]
RewriteCond %{HTTP_USER_AGENT} "the beast" [NC]
RewriteRule / http://%{REMOTE_ADDR}/NOTICE-%{REMOTE_ADDR}-IS-INFECTED-OR-HACKING.html [R,L]
I would also suggest that if you plan to have a lot of rules, it would be easier to manage them by making a separate Apache config file just for your rewrites. That way all of your rewrites can be stored and organized in one place. If you use virtual hosts on your Apache installation you can still also make individual entries within your <VirtualHost> sections that will apply only to that virtual host. You can make a separate config file by putting this in your httpd.conf:
Include rewrites.conf
The file can have all of the same syntax as your regular httpd.conf including comments, and is treated like the entire file was just pasted in to your main config.