wp-login.php and mod security

sahostking

Well-Known Member
May 15, 2012
337
4
68
Cape Town, South Africa
www.hostking.co.za
cPanel Access Level
Root Administrator
Hi guys,

We moved from paid Atomic Rules to Comodo WAF rules and all works well. Just one thing we cannot get working is that wp-login.php and administrator/index.php for Joomla and Wordpress websites get hit a lot as per below. Clients are in CloudLinux LVE so only affects the one customer but still it happens to random ones each day.

Already posted on Comodo Forums aswell as webhostingtalk.com but still waiting on response. I get quicker response here :)
Code:
96.30.62.175 - - [29/Sep/2014:07:56:33 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:34 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:35 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:35 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:36 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:37 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:37 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:38 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:38 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:39 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:40 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:41 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:42 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:43 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:43 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:44 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:44 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:45 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:46 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:46 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:47 +0200] "POST /wp-login.php HTTP/1.0" 508 7287 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:47 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:48 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:49 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:49 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:50 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:51 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
96.30.62.175 - - [29/Sep/2014:07:56:52 +0200] "POST /wp-login.php HTTP/1.0" 200 3810 "-" "-"
I currently use this but does not seem to work:

Code:
# WordPress Brute Force and Comment Spam Protection

<LocationMatch "/(wp-login.php|wp-comments-post.php)">
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:00110
SecRule user:bf_block "@gt 0" "deny,status:403,log,id:00111,msg:'IP address blocked for 5 minutes. More than 3 POST requests to wp-login.php or wp-comments-post.php within 10 seconds.'"
SecRule REQUEST_METHOD "^POST$" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/10,id:00112"
SecRule ip:bf_counter "@gt 3" "t:none,setvar:user.bf_block=1,expirevar:user.bf_block=300,setvar:ip.bf_counter=0"
</LocationMatch>

# Joomla Brute Force Protection
<LocationMatch "/administrator/index.php">
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:00113
SecRule user:bf_block "@gt 0" "deny,status:403,log,id:00114,msg:'IP address blocked for 5 minutes. More than 3 Joomla POST requests within 10 seconds.'"
SecRule REQUEST_METHOD "^POST$" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/10,id:00115"
SecRule ip:bf_counter "@gt 3" "t:none,setvar:user.bf_block=1,expirevar:user.bf_block=300,setvar:ip.bf_counter=0"
</LocationMatch>
 

quizknows

Well-Known Member
Oct 20, 2009
1,008
86
78
cPanel Access Level
DataCenter Provider
Those rules rely entirely on rate limiting and are not very good in my opinion. They are also unnecessarily using two collections instead of one.

Here are the current wp-login rules I'm using:

Code:
#Block WP logins with no referring URL
<Locationmatch "/wp-login.php">
SecRule REQUEST_METHOD "POST"  "deny,status:401,id:5000130,chain,msg:'wp-login request blocked, no referer'"
SecRule &HTTP_REFERER "@eq 0"
</Locationmatch>

#Wordpress Brute Force detection
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},id:5000134
<Locationmatch "/wp-login.php">
# Setup brute force detection.
# React if block flag has been set.
SecRule ip:bf_block "@gt 0" "deny,status:401,log,id:5000135,msg:'ip address blocked for 5 minutes, more than 10 login attempts in 3 minutes.'"
# Setup Tracking.  On a successful login, a 302 redirect is performed, a 200 indicates login failed.
SecRule RESPONSE_STATUS "^302" "phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:5000136"
SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000137"
SecRule ip:bf_counter "@gt 10" "t:none,setvar:ip.bf_block=1,expirevar:ip.bf_block=300,setvar:ip.bf_counter=0"
</locationmatch>
 

cosmin

Well-Known Member
Feb 6, 2002
152
0
316
43
Bucuresti
Hello!

I put this in /usr/local/apache/conf/modsec2.user.conf before last line (Include /usr/local/apache/conf/modsec2.whitelist.conf) but no effect.
Any ideea please? In last 2 days we are under continuu attack with /wp-login.php

Many thanks!
 

quizknows

Well-Known Member
Oct 20, 2009
1,008
86
78
cPanel Access Level
DataCenter Provider
Are you getting any ModSecurity messages in your apache error_log at all?

Are you sure that ModSecurity is actually compiled in under EasyApache? (it is possible to have the config files but no module to use them).

Also make sure your main directives are set in modsec2.user.conf such as:

Code:
SecUploadDir /tmp
SecTmpDir /tmp
SecDataDir /tmp
SecRequestBodyAccess On
And last but not least, you must restart Apache after editing any modsecurity configs, or the changes will not take effect until the next restart of the service.
 

cosmin

Well-Known Member
Feb 6, 2002
152
0
316
43
Bucuresti
Yes, I have many messages in error_log about modsecurity.

I put your lines with /tmp in modsec2.user.conf but no effect....

- - - Updated - - -

Nobody say is necesarry to enable "cPHulk Brute Force Protection" from WHM. Now is working :D
cPHulk Brute Force Protection cand run in the same time with csf? Not any problem/conflict?

Thanks!
 

JaredR.

Well-Known Member
Feb 25, 2010
1,834
22
143
Houston, TX
cPanel Access Level
Root Administrator
There will be a conflict if you enable both cPHulk and the LFD component of CSF. cPHulk and LFD do the same thing and enabling them both at the same time will eventually cause a conflict.
 

quizknows

Well-Known Member
Oct 20, 2009
1,008
86
78
cPanel Access Level
DataCenter Provider
Yes, I have many messages in error_log about modsecurity.

I put your lines with /tmp in modsec2.user.conf but no effect....

- - - Updated - - -

Nobody say is necesarry to enable "cPHulk Brute Force Protection" from WHM. Now is working :D
cPHulk Brute Force Protection cand run in the same time with csf? Not any problem/conflict?

Thanks!

cphulk should be completely irrelevant here, sounds like you got the modsec config straightened out though.


There will be a conflict if you enable both cPHulk and the LFD component of CSF. cPHulk and LFD do the same thing and enabling them both at the same time will eventually cause a conflict.
What conflict are you talking about? They work fundamentally differently, and while it's not necessary to have both, they don't really conflict. I've never seen an issue where having both cPHulk and CSF/LFD running caused any actual problems, this being over 4-5 years on literally thousands of servers. cPHulk will lock out usernames, where as LFD/CSF actually will block IPs in the servers firewall (iptables). Typically I recommend CSF over cphulk, since CSF won't lock you out of root on your own server during a brute force (and yes, I know about the IP whitelist).
 

qwerty

Well-Known Member
Jan 21, 2003
214
2
168
Does anyone know how to correctly modify these rules to 1) block after 5 unsuccessful attempts instead of 10 2) make it a PERM block not a temporary 5 minute block
 

quizknows

Well-Known Member
Oct 20, 2009
1,008
86
78
cPanel Access Level
DataCenter Provider
Does anyone know how to correctly modify these rules to 1) block after 5 unsuccessful attempts instead of 10 2) make it a PERM block not a temporary 5 minute block
For the first part:

SecRule ip:bf_counter "@gt 10"

Change that to @gt 5 (or whatever number)

For the 2nd part (block time), this is what sets the 5 minutes:

expirevar:ip.bf_block=300

You could raise the number (300s = 5 mins), or probably omit that to just not expire it. However, what I do is just use LF_MODSEC in csf. If they keep trying during that 5 minute window, CSF will block their IP in iptables for you which is better anyway.
 

sahostking

Well-Known Member
May 15, 2012
337
4
68
Cape Town, South Africa
www.hostking.co.za
cPanel Access Level
Root Administrator
Those rules rely entirely on rate limiting and are not very good in my opinion. They are also unnecessarily using two collections instead of one.

Here are the current wp-login rules I'm using:

Code:
#Block WP logins with no referring URL
<Locationmatch "/wp-login.php">
SecRule REQUEST_METHOD "POST"  "deny,status:401,id:5000130,chain,msg:'wp-login request blocked, no referer'"
SecRule &HTTP_REFERER "@eq 0"
</Locationmatch>

#Wordpress Brute Force detection
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},id:5000134
<Locationmatch "/wp-login.php">
# Setup brute force detection.
# React if block flag has been set.
SecRule ip:bf_block "@gt 0" "deny,status:401,log,id:5000135,msg:'ip address blocked for 5 minutes, more than 10 login attempts in 3 minutes.'"
# Setup Tracking.  On a successful login, a 302 redirect is performed, a 200 indicates login failed.
SecRule RESPONSE_STATUS "^302" "phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:5000136"
SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000137"
SecRule ip:bf_counter "@gt 10" "t:none,setvar:ip.bf_block=1,expirevar:ip.bf_block=300,setvar:ip.bf_counter=0"
</locationmatch>
Awesome. Just placed this in userdata custom ruleset and it worked instantly. Blocked rules based on this id.

Thanks.
 

abdelhost77

Well-Known Member
Apr 25, 2012
111
2
68
Morocco
cPanel Access Level
Root Administrator
Awesome. Just placed this in userdata custom ruleset and it worked instantly. Blocked rules based on this id.

Thanks.
It works also for me thanks :)

i would like to use the same rule to protect against xmlprc.php attaks , is that possible , what should i modify except filename and rule ID ?
 
Last edited:

quizknows

Well-Known Member
Oct 20, 2009
1,008
86
78
cPanel Access Level
DataCenter Provider
You can adapt one of these rules for XMLRPC as follows:

Code:
#Block XMLRPC no referring URL
SecRule REQUEST_METHOD "POST"  "deny,status:401,id:4784627,chain,msg:'xmlrpc request blocked, no referer'"
SecRule &HTTP_REFERER "@eq 0" "chain"
SecRule REQUEST_URI "xmlrpc.php"
This may interfere with some normal uses of xmlrpc but I have not had any complaints. If a customer wants to POST legitimate data to xmlrpc.php they just need to specify something (anything) as a referer in their HTTP headers.
 
  • Like
Reactions: postcd

abdelhost77

Well-Known Member
Apr 25, 2012
111
2
68
Morocco
cPanel Access Level
Root Administrator
You can adapt one of these rules for XMLRPC as follows:

Code:
#Block XMLRPC no referring URL
SecRule REQUEST_METHOD "POST"  "deny,status:401,id:4784627,chain,msg:'xmlrpc request blocked, no referer'"
SecRule &HTTP_REFERER "@eq 0" "chain"
SecRule REQUEST_URI "xmlrpc.php"
This may interfere with some normal uses of xmlrpc but I have not had any complaints. If a customer wants to POST legitimate data to xmlrpc.php they just need to specify something (anything) as a referer in their HTTP headers.


Please find what i put in mine :



Code:
#Block xmlrpc with no referring URL
<Locationmatch "/xmlrpc.php">
SecRule REQUEST_METHOD "POST"  "deny,status:401,id:5000140,chain,msg:'xmlrpc request blocked, no referer'"
SecRule &HTTP_REFERER "@eq 0"
</Locationmatch>

#Wordpress Brute Force detection
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},id:5000144
<Locationmatch "/xmlrpc.php">
# Setup brute force detection.
# React if block flag has been set.
SecRule ip:bf_block "@gt 0" "deny,status:401,log,id:5000145,msg:'ip address blocked for 5 minutes, more than 10 login attempts in 3 minutes.'"
# Setup Tracking.  On a successful login, a 302 redirect is performed, a 200 indicates login failed.
SecRule RESPONSE_STATUS "^302" "phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:5000146"
SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000147"
SecRule ip:bf_counter "@gt 10" "t:none,setvar:ip.bf_block=1,expirevar:ip.bf_block=300,setvar:ip.bf_counter=0"
</locationmatch>


Do you think it is OK ?
 

quizknows

Well-Known Member
Oct 20, 2009
1,008
86
78
cPanel Access Level
DataCenter Provider
The first rule will work OK. The reason I used the REQUEST_URI instead of LocationMatch for it is in case someone needs the rule whitelisted it is easier. A locationmatch whitelist won't work right if the rule itself is already in a locationmatch section. Your first rule, and the one you quoted that I posted, will do exactly the same thing.

The second one will work, but for the wrong reasons. xmlrpc does not 302 for successful requests like wp-login does. Basically what that 2nd rule would end up doing is simply rate limiting the number of calls that can be made to xmlrpc that result in normal 200 OK returns. If any IP hits an xmlrpc file more than 10 times in 3 minutes it will be blocked from xmlrpc files, regardless of any other attributes of the request. The RESPONSE_STATUS "^302" line is probably not needed at all. Honestly, it's probably not a bad rule to try out.
 

Hedloff

Well-Known Member
Jun 7, 2004
142
5
168
Up north!
cPanel Access Level
DataCenter Provider
Does anyone have a working Joomla Brute Force rule?
Have tried some before, but I always end up removing it because they cause problems with other extensions/modules inside Joomla.
 

abdelhost77

Well-Known Member
Apr 25, 2012
111
2
68
Morocco
cPanel Access Level
Root Administrator
  • Like
Reactions: postcd

quizknows

Well-Known Member
Oct 20, 2009
1,008
86
78
cPanel Access Level
DataCenter Provider
I found this in :

Using MoSec for Joomla and WP Brute force - Hosting Security and Technology - Web Hosting Talk

and it works for me .



# Block Joomla scans that are looking for sites to target; frequently they lack both UA and Referer fields
SecRule REQUEST_URI "/administrator/index.php" "deny,status:411,id:5000223,chain,msg:'Joomla admin access blocked due to No UA and No referer'"
SecRule &HTTP_REFERER "@eq 0" "chain"
SecRule &HTTP_User-Agent "@eq 0"
That's my rule :) I can confirm it does stop a fair amount of abusive traffic. This one can help too:

Code:
# Block Joomla logins with no referring URL
SecRule REQUEST_URI "/administrator/index.php" "deny,status:411,id:5000224,chain,msg:'Joomla login request blocked, no referer'"
SecRule REQUEST_METHOD "POST" "chain"
SecRule &HTTP_REFERER "@eq 0"
 
  • Like
Reactions: postcd

JacobHansen

Member
Mar 20, 2013
13
0
1
cPanel Access Level
Root Administrator
Those rules rely entirely on rate limiting and are not very good in my opinion. They are also unnecessarily using two collections instead of one.

Here are the current wp-login rules I'm using:

Code:
#Block WP logins with no referring URL
<Locationmatch "/wp-login.php">
SecRule REQUEST_METHOD "POST"  "deny,status:401,id:5000130,chain,msg:'wp-login request blocked, no referer'"
SecRule &HTTP_REFERER "@eq 0"
</Locationmatch>

#Wordpress Brute Force detection
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},id:5000134
<Locationmatch "/wp-login.php">
# Setup brute force detection.
# React if block flag has been set.
SecRule ip:bf_block "@gt 0" "deny,status:401,log,id:5000135,msg:'ip address blocked for 5 minutes, more than 10 login attempts in 3 minutes.'"
# Setup Tracking.  On a successful login, a 302 redirect is performed, a 200 indicates login failed.
SecRule RESPONSE_STATUS "^302" "phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0,id:5000136"
SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000137"
SecRule ip:bf_counter "@gt 10" "t:none,setvar:ip.bf_block=1,expirevar:ip.bf_block=300,setvar:ip.bf_counter=0"
</locationmatch>
I've attempted adding these to the file:
/usr/local/apache/conf/modsec2.user.conf however I am not seeing any effect. I have some earlier logs from mod_security from earlier this morning, however there is an ongoing bruteforce attack going, and adding this rule has had no effect. I have restarted the webserver (running Litespeed). I have confirmed the there is a huge number of login attempts on the same site from the same IP address.

The rules show up (although not as one but several) in the ModSecurity Tools rules list. I use CSF and cpHulk is disabled.

Any idea why this is not working as intended?