WordPress and Joomla are probably the two most popular web apps that are massively used by end users to create fast websites. But that popularity also comes with high risks. That’s why today we will explore some ways to block brute force attacks on WordPress and Joomla using ModSecurity rules.
WP and Joomla are popular because they are easy to install, the learning curve is pretty fast, they are translated into lot of languages, and offer a fast and 1 click way to get your website running in just minutes.
And because this two pieces of software are two of the most popular ones, this leads to be two of the most attacked apps too. Brute force attacks are the most common attacks on this platforms.
Brute force attacks try to guess your user and password credentials in order to gain access to your private administrator area. On this post we will cover how to protect and stop brute force attacks on WordPress and Joomla using custom mod_security rules.
Install Mod_Security
In order to setup a protection to block brute force attacks on WordPress and Joomla you need to make sure that you are already running Mod_Security on your server. If you don’t have modsecurity installed, you can do it by following this guide: Install ModSecurity on cPanel
Step by Step: Block brute force attacks on WordPress and Joomla
Let’s create a file called bruteforce.conf on this location: /usr/local/apache/conf/bruteforce.conf
Type the following command:
nano -w /usr/local/apache/conf/bruteforce.conf
Then paste this content inside:
# WordPress & Joomla ModSecurity Brute Force Rules # ----------------------------------------------------------------------------- # TX.max_requests - # of requests allowed during x period of time # TX.requests_ttl - time in seconds # TX.block_ttl - block time in seconds # ----------------------------------------------------------------------------- SecRequestBodyAccess On SecDataDir /tmp SecAction "phase:1,pass,setvar:TX.max_requests=6,setvar:TX.requests_ttl=180,setvar:TX.block_ttl=900,initcol:ip=%{REMOTE_ADDR},nolog,id:5001000" SecRule IP:blocked "@eq 1" "phase:1,drop,log,id:5001001" # WordPress Anti Brute Force Rules <LocationMatch "/wp-login.php"> SecAction "phase:2,chain,nolog,id:5001002" SecRule REQUEST_METHOD "^POST$" "chain" SecRule ARGS_POST_NAMES "^log$" "chain" SecRule ARGS_POST_NAMES "^pwd$" "chain" SecAction "setvar:ip.request_count=+1,expirevar:ip.request_count=%{TX.requests_ttl}" SecRule IP:request_count "@ge %{TX.max_requests}" "phase:2,drop,setvar:ip.blocked=1,expirevar:ip.blocked=%{TX.block_ttl},log,msg:'Bloqueado por %{TX.block_ttl} segundos',id:5001003" # Joomla Anti Brute Force Rules <LocationMatch "/administrator/index.php"> SecAction "phase:2,chain,nolog,id:5001012" SecRule REQUEST_METHOD "^POST$" "chain" SecRule ARGS_POST_NAMES "^username$" "chain" SecRule ARGS_POST_NAMES "^passwd$" "chain" SecRule ARGS_POST:option "^com_login$" "chain" SecRule ARGS_POST:task "^login$" "chain" SecAction "setvar:ip.request_count=+1,expirevar:ip.request_count=%{TX.requests_ttl}" SecRule IP:request_count "@ge %{TX.max_requests}" "phase:2,drop,setvar:ip.blocked=1,expirevar:ip.blocked=%{TX.block_ttl},log,msg:'Bloqueado por %{TX.block_ttl} segundos',id:5001013" # Old Joomla installations <LocationMatch "/administrator/index.php"> SecAction "phase:2,chain,nolog,id:5001022" SecRule REQUEST_METHOD "^POST$" "chain" SecRule ARGS_POST_NAMES "^usrname$" "chain" SecRule ARGS_POST_NAMES "^pass$" "chain" SecAction "setvar:ip.request_count=+1,expirevar:ip.request_count=%{TX.requests_ttl}" SecRule IP:request_count "@ge %{TX.max_requests}" "phase:2,drop,setvar:ip.blocked=1,expirevar:ip.blocked=%{TX.block_ttl},log,msg:'Bloqueado por %{TX.block_ttl} segundos',id:5001023"
Loading Anti Brute Force rules
Now let’s configure ModSecurity to load those brute force protection rules, run this command:
echo "Include /usr/local/apache/conf/bruteforce.conf" >> /usr/local/apache/conf/modsec2.user.conf
Restart Apache to apply changes:
service httpd restart
The resulsts of this brute force protection for WordPress and Joomla will be logged at Apache error log
Los resultados del bloqueo podremos verlos en el log de Apache. Tras 5 intentos fallidos de conexión la IP responsable será bloqueada:
Before wp-login.php login attempts were looking like this:
111.111.111.111 - - [01/Dec/2016:09:31:37] "POST /wp-login.php HTTP/1.0" 200 222.222.222.222 - - [01/Dec/2016:09:31:38] "POST /wp-login.php HTTP/1.0" 200 111.111.111.111 - - [01/Dec/2016:09:31:39] "POST /wp-login.php HTTP/1.0" 200
After setting up the brute force rules, you should notice 406 status on each brute force attack:
111.111.111.111 - - [01/Dec/2016:09:35:41] "POST /wp-login.php HTTP/1.0" 406 - 222.222.222.222 - - [01/Dec/2016:09:35:43] "POST /wp-login.php HTTP/1.0" 406 - 111.111.111.111 - - [01/Dec/2016:09:35:45] "POST /wp-login.php HTTP/1.0" 406 -
If this rules cause you any problems, can be deactivated by editing /usr/local/apache/conf/modsec2.user.conf file, and then remove the following line:
Include /usr/local/apache/conf/bruteforce.conf
Then restart Apache to apply changes:
service httpd restart
That’s all, now you know anothe way to block brute force attacks on WordPress and Joomla. Remember we’ve also written about how to install Comodo WAF on cPanel, which also includes very good Brute Force protection rules for common CMS like WP and Joomla.
We found these rules really useful.
Two things:
(1) The code contains 3x but these were not closed so we had to add to the end of each section.
(2) Would it be possible to extend the WordPress code to protect the xmlrpc.php file from flooding? Do you know if it uses similar arguments?
Thanks very much!