Attention! Helicon Tech Blog has moved to www.helicontech.com/articles/

Wednesday, June 10, 2009

Prevent DoS attacks with Helicon Ape mod_evasive module

Hello, folks! Security is an important subject and we are trying to include some protection features into our software. Perhaps you have already heard about HotlinkBlocker and its reincarnation in Helicon Ape — mod_hotlink module. Cool stuff, but we want to give you more. Helicon Ape 1.2.0.20 brings us mod_evasive, the module destined to protect your web-server from DoS and brute-force attacks. Sounds vague, so we'll provide a little explanation.

DoS is not an Operating System:)

In the security circles, familiar acronym «DoS» has nothing to do with well-known operating system. It stands for «Denial-Of-Service» and means an attempt to make a computer resource unavailable to its intended users. Also there is another term - «Distributed Denial-Of-Service attack» (DDoS attack).

As opposed to DoS, brute-force attack is commonly aimed at getting some access to a protected resource. For example, a computer hacker is trying a large number of possible passwords to crack a needed user account. In fact, lots of users use very simple passwords and hackers are gathering these passwords in special databases to use during brute-force attack.
More information may be found here:

mod_evasive

The module was originally written for Apache and we tried to support its syntax to the maximum extent. Moreover, Ape implementation has a potential for further development and we are waiting for your suggestions and criticism.

To enable the module you should open Helicon Ape server configuration (httpd.conf file) and comment out LoadModule directive corresponding to mod_evasive:


Now we are ready to write mod_evasive configuration. The module directives should be written only inside httpd.conf file (per VirtualHost configuration is also supported).

There are five directives which have to be configured, otherwise the module won't work. We haven't set any default values for these directives because their configuration is highly dependant on your server's characteristics. Here are the five required directives:
  • DOSPageInterval —  Sets a minimum accessible interval between two requests to a page from the same IP.
  • DOSSiteInterval —  Sets a minimum accessible interval between two requests to a site from the same IP.
  • DOSPageCount —  Sets the limit for a number of too short requests to the same page
  • DOSSiteCount —  Sets the limit for a number of too short requests to the same site
  • DOSBlockingPeriod —  How much time bad IP should be blocked.
Now we need to explain you mod_evasive logic. The module counts how many «too short» requests are made from same IP to various URLs and to the whole site. «Too short» means less than accessible interval set by DOSPageInterval and DOSSiteInterval directives. When an IP exceeds the count threshold, it will be blocked during a period set by DOSBlockingPeriod directive. DOSPageInterval, DOSSiteInterval and DOSBlockingPeriod values should be specified in seconds (real numbers are also supported to define more accurate intervals.

Note! You should carefully set mod_evasive configuration according to your server load! In case of incorrect configuration, legal users might be blocked. Here is an example of a minimal possible mod_evasive configuration. Please don't use it without testing!

<IfModule evasive_module>
        DOSPageInterval 1
        DOSSiteInterval 1
        DOSPageCount 10
        DOSSiteCount 200
        DOSBlockingPeriod 60
</IfModule>

This configuration is enough to start blocking attackers. On the next step we will tell you about the blocking behavior.

What happens to bad guys

According to original mod_evasive behaviour, the module sends 403 (Forbidden) code. Actually the blocked response is faster than the common one, because Ape stops request at this point and IIS processes only BeginRequest and EndRequest notification event.

In addition we've invented DOSCloseSocket directive (not supported in Apache) which is disabled by default. If you enable this directive, mod_evasive will send 403 code and close connection socket. It means an attacker should create a new connection and it's pretty good for you as long as this process takes some time.

How to manage a hit list

There are two directives to manage hit list. The first one is DOSHashTableSize which allows you to set a maximum size of the list. Default value is 1024. Each item in the hit list corresponds to an IP address and you might dynamically change this value during DoS attack. Just modify DOSHashTableSize value in httpd.conf and Ape will automatically update mod_evasive configuration. Just FYI, the module is using special cleanup algorithm in case of overflow. Another way to manage hit list is DOSWhiteList directive. It allows to specify IPs which should never be blocked. Both IPv4 and IPv6 formats are supported, moreover, you may use wildcard to add a group of IP addresses into the list. Example:

DOSWhiteList 127.0.0.1 10.0.0.*

Connection with a system (for advanced users only)

There is one more useful feature in mod_evasive. It is DOSSystemCommand directive which gives you a chance to communicate with OS through command execution. You should be careful with this feature because it might be insecure and might cause NTFS permissions issue. So, a command delivered to mod_evasive through DOSSystemCommand directive, will execute each time the module decides that an IP is bad. So, the command will be executed not for all 403 responses, but only for those given in response to malicious requests.


We should notice again that the user running the Application pool should have sufficient rights to execute the command. In most cases it's pretty hard because web-services are run by non-previleged user with limited skills. In this case you should execute a command under another account (e.g. Administrator). Windows has runas command which provides needed functional with one disadvandage — it can't get password through arguments. But, there are a few solutions to this problem. For example, you may use the following script to run the command(s) on behalf of another user specifying his username and password:

' *********************************************************************************
' * THIS PROGRAM IS OFFERED AS IS AND MAY BE FREELY MODIFIED OR ALTERED AS *
' * NECESSARY TO MEET YOUR NEEDS. THE AUTHOR MAKES NO GUARANTEES OR WARRANTIES, *
' * EXPRESS, IMPLIED OR OF ANY OTHER KIND TO THIS CODE OR ANY USER MODIFICATIONS. *
' * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED IN A SECURED LAB *
' * ENVIRONMENT. USE AT YOUR OWN RISK. *
' *********************************************************************************

On Error Resume Next
dim WshShell,oArgs,FSO

set oArgs=wscript.Arguments

if InStr(oArgs(0),"?")<>0 then
wscript.echo VBCRLF & "? HELP ?" & VBCRLF
Usage
end if

if oArgs.Count <3 then
wscript.echo VBCRLF & "! Usage Error !" & VBCRLF
Usage
end if

sUser=oArgs(0)
sPass=oArgs(1)&VBCRLF
sCmd=oArgs(2)

set WshShell = CreateObject("WScript.Shell")
set WshEnv = WshShell.Environment("Process")
WinPath = WshEnv("SystemRoot")&"\System32\runas.exe"
set FSO = CreateObject("Scripting.FileSystemObject")

if FSO.FileExists(winpath) then
'wscript.echo winpath & " " & "verified"
else
wscript.echo "!! ERROR !!" & VBCRLF & "Can't find or verify " & winpath &"." & /
VBCRLF & "You must be running Windows 2000 for this script to work."
set WshShell=Nothing
set WshEnv=Nothing
set oArgs=Nothing
set FSO=Nothing
wscript.quit
end if

rc=WshShell.Run("runas /user:" & sUser & " " & CHR(34) & sCmd & CHR(34), 2, FALSE)
Wscript.Sleep 30 'need to give time for window to open.
WshShell.AppActivate(WinPath) 'make sure we grab the right window /
to send password to
WshShell.SendKeys sPass 'send the password to the waiting window.

set WshShell=Nothing
set oArgs=Nothing
set WshEnv=Nothing
set FSO=Nothing

wscript.quit

'************************
'* Usage Subroutine *
'************************
Sub Usage()
On Error Resume Next
msg="Usage: cscript|wscript vbrunas.vbs Username Password Command" /
& VBCRLF & VBCRLF & "You should use the full path /
where necessary and put long file names or commands" & VBCRLF & /
"with parameters in quotes" & VBCRLF & VBCRLF &/
"For example:" & VBCRLF &" cscript vbrunas.vbs /
quilogy\jhicks luckydog e:\scripts\admin.vbs" & VBCRLF & /
VBCRLF &" cscript vbrunas.vbs quilogy\jhicks luckydog " & /
CHR(34) &"e:\program files\scripts\admin.vbs 1stParameter 2ndParameter" & /
CHR(34)& VBCRLF & VBCRLF & VBCLRF & "cscript vbrunas.vbs/
 /?|-? will display this message."

wscript.echo msg

wscript.quit

end sub
With the above script being used, mod_evasive can be configured as follows:
DOSSystemCommand "cscript ra.vbs user password command"
It is considered good practice to add Windows firewall rule for bad IP addresses. Here is a possible solution:
DOSSystemCommand "cscript ra.vbs mod_evasive_user pwd \"netsh advfirewall firewall
add rule name=\"mod_evasive %s blocking\" dir=in protocol=TCP localport=80
remoteip=%s action=block\""

Please notice that %s variable contains a string representation of blocking IP.

That's all

We hope the article will help you create correct configuration and enjoy mod_evasive. But we wish your server never face the situations where mod_evasive is needed :)

Yours sincerely, 
HeliconTech Team

4 comments:

  1. Can you have something for Windows Server 2003?

    ReplyDelete
  2. This module should work just fine on 2003 as well.
    Please give it a try.

    ReplyDelete
  3. Can you teach me how to use the script.

    I copied the script and save as ra.vbs

    It didn't work

    ReplyDelete
  4. Hi, could you please put your question to our forum (http://www.helicontech.com/forum/forum_topics-FID-11.htm) and we'll give you an explicit answer.

    ReplyDelete