Stop WordPress Brut Force Attacks Automatically Using ModSecurity ConfigServer

phpAddict

Active Member
With so many of my accounts being WordPress sites these days I was constantly being alerted by CSF of excessive resource usage on wp-login.php pages several times a day. Even though I have plugins installed that ignore logins after a few failed attempts, hackers wouldn't notice that or the scripts wouldn't stop so they continued to hammer my server. CSF is great but since it didn't provide IP addresses of the offenders in the email alerts I always had to login and view recent visitors on that account, find the offending ip, go back into CSF and black list the IP. Only takes a few minutes, but it gets to be annoying after a while and when it happens in the middle of the night I don't notice it until the next morning. So I began thinking of a way to get WordPress and CSF to work together to automatically block these IPs and of course someone already did so I figured I'd share since I'm sure I'm not the only one with this issue...

https://smyl.es/how-to-block-wp-log...panel-mod-security-and-configserver-firewall/

I changed some of the timings (10 failed logins within 15 minutes will block for 60 minutes). It's optional to have it tied in with CSF and seems it may increase resource usage which may be an issue on VPS's. If you do enable mod_security and CSF to commingle then the temporary block will not work, as soon as mod_security's rule is triggered CSF will go into action and add the IP to the permanent deny list. Not necessarily a problem but important to understand so you know where to correct users that manage to get themselves blocked (of course that would never happen ;)).

I plan to take this small list of rules and apply it to other pages that seem to get hammered on my server (contact forms, custom login pages, etc.)

I saw from previous threads and their website that there are other common rules to add to ModSecurity, and @Dan you seem to use it religiously. Do these rules change regularly? Would you recommend applying any particular rule sets? I read some are buggy or cause excessive resource usage so I'd like to hear from someone that's used it for a while.
 
Hi Josh!

You're right I've been using ModSecurity for a while here although I would also say that no one would (or should) want to do it the way I do :rolleyes: I actually go through the modsec_audit log daily and find failed logins or calls for files that are known to be bad and block them in CSF manually. At one point CSF and ModSecurity actually played nicely together and CSF would read the modsec_audit log and add blocks from it but once ModSecurity changed their log format that stopped working. I tried fixing it for a while but eventually gave up. I also have it set so cPanel doesn't dump the ModSecurity log to a DB, that drove me crazy for a bit.

To answer your question I just run the common core ruleset which are now by OWASP. In the past (talking several years now) I did try a couple of alternative rulesets and they definitely took a lot of resources which was why I just went back to the core ruleset. They have a mailing list that I'm on and I should update them but to be honest I haven't in a while because, dang it, it's working and working well.

If you have users that get themselves blocked by CSF the file to edit is /etc/csf/csf.deny. Additionally I'll also point out that unless you edited the LocationMatch in the code you're using that it will work for all WP installs on the server since it's watching simply for wp-login.php so you do it once for one server and you're done.

Let me know how this code works for you!

Dan
 
Just an update. This has been a life saver. Being that I use to manually block IPs, this has done that job for me automatically and has saved me much frustration. Hackers now just block themselves for me.

Recently one of my client's accounts that had a vulnerable WP plugin got hacked and the hacker placed a backdoor file in many locations called indonesia.php . Since I've identified 25 different IPs accessing this file I'm now going to use this same method to block any IP that accesses any indonesia.php file. I'm confident I've removed the security flaw and all the backdoors, but just to be safe it makes me very happy to see that I can use these hackers resources against them using ModSecurity.
 
It's an exercise in frustration and futility blocking IP addresses of hackers, script kiddies and other undesirables trying to gain access to your WP site(s). Most of these scum bags are either using botnets, which have literally 100's of thousands of infected computers/servers at their disposal...or... they're using daisy chained anon proxies etc.

I've been using ZB Block http://www.spambotsecurity.com/zbblock.php (it's free) on ALL my WP site for the past 2 years. Unlike WP security plugins, scum bags out to cause trouble, don't even make it to your WP login page, they're block even before WP loads ;)

This php security script is designed to detect certain behaviors detrimental to websites, or known bad addresses attempting to access your site. It then will send the bad robot (usually) or hacker an authentic 403 FORBIDDEN page with a description of what the problem was. If the attacker persists, then they will be served up a permanently reccurring 503 OVERLOAD message with a 24 hour timeout.

There are additional country blocks which can easily be added to the custom script file. ZB Block secures you against all manner of crap such as brute force attacks, sql injections, recursive folder & Author sniffing, fake google bots etc, in fact anything that's at your site to cause you headaches ZB Block pretty much has your back!

As long as the site is running php you can impliment the security tool.

PS... I'm not associated to the software, I'm just spreading the word.
 
Thanks for that @AUDave it looks like a great script. I'll likely be giving it a try. If for nothing else the fact that it uses a community database for blocking IPs rather than my server having to build its own. My only concern is I'd be afraid of blocking myself as I do some unique things when testing and developing sites.
 
With so many of my accounts being WordPress sites these days I was constantly being alerted by CSF of excessive resource usage on wp-login.php pages several times a day. Even though I have plugins installed that ignore logins after a few failed attempts, hackers wouldn't notice that or the scripts wouldn't stop so they continued to hammer my server. CSF is great but since it didn't provide IP addresses of the offenders in the email alerts I always had to login and view recent visitors on that account, find the offending ip, go back into CSF and black list the IP. Only takes a few minutes, but it gets to be annoying after a while and when it happens in the middle of the night I don't notice it until the next morning. So I began thinking of a way to get WordPress and CSF to work together to automatically block these IPs and of course someone already did so I figured I'd share since I'm sure I'm not the only one with this issue...

https://smyl.es/how-to-block-wp-log...panel-mod-security-and-configserver-firewall/

I changed some of the timings (10 failed logins within 15 minutes will block for 60 minutes). It's optional to have it tied in with CSF and seems it may increase resource usage which may be an issue on VPS's. If you do enable mod_security and CSF to commingle then the temporary block will not work, as soon as mod_security's rule is triggered CSF will go into action and add the IP to the permanent deny list. Not necessarily a problem but important to understand so you know where to correct users that manage to get themselves blocked (of course that would never happen ;)).

I plan to take this small list of rules and apply it to other pages that seem to get hammered on my server (contact forms, custom login pages, etc.)

I saw from previous threads and their website that there are other common rules to add to ModSecurity, and @Dan you seem to use it religiously. Do these rules change regularly? Would you recommend applying any particular rule sets? I read some are buggy or cause excessive resource usage so I'd like to hear from someone that's used it for a while.

Hello.

I installed the script and it does not seem to work. I am seeing an IP accessing wp-login.php well within the parameters I have set in the script, but it is not blocking the IP in CSF. I have double checked that the LF_MODSEC setting is set in the CSF configuration. I also restarted CSF and Apache several times.

Are there any settings in ModSecurity that need to be changed perhaps?

Another wild card - I am using the NginxCP cPanel plugin, for a reverse proxy. I wouldn't think that this would affect it, since the script looks at access of wp-login.php, and should not care about what is going on with HTTP...

Any words of wisdom are appreciated.
 
I don't recall anything special to get it working. I made a couple minor changes to the times, but I believe it was working right away. Copy and paste your ModeSec script here and I'll have a looksee.
 
I don't recall anything special to get it working. I made a couple minor changes to the times, but I believe it was working right away. Copy and paste your ModeSec script here and I'll have a looksee.

Hi Josh,

Thanks much for your help.

Here is the script:

Code:
SecUploadDir /tmp
SecTmpDir /tmp
SecDataDir /tmp
SecRequestBodyAccess On
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:5000134

<Locationmatch "/wp-login.php">
    # Setup brute force detection.

    # React if block flag has been set.

SecRule user:bf_block "@gt 0" "deny,status:401,log,id:5000135,msg:'ip address blocked for 60 minutes, more than 10 login attempts in 15 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:user.bf_block=1,expirevar:user.bf_block=3600,setvar:ip.bf_counter=0"

</locationmatch>
ErrorDocument 401 default
 
It looks good, but try changing....
Code:
SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180,id:5000137"
...to...
Code:
SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/900,id:5000137"
This section is where it counts the failed login attempts. I changed it from 180 seconds (3 minutes) to 900 seconds (15 minutes). Certainly a hacker trying to brute force your WP site would do 5 failed logins within 3 minutes, but just in case they're slow to type. :p

Additionally, double check in ConfigServer's Firewall Configuration, that the "LF_MODSEC" setting is set to something other than 0, I recommend 5 which should be the default anyway. This is what gets your ConfigServer and ModSec working together. Without setting this, ModSec will only temporarily block offenders for an hour. Below is my entire script...

Code:
SecUploadDir /tmp
SecTmpDir /tmp
SecDataDir /tmp
SecRequestBodyAccess On
SecAction phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},initcol:user=%{REMOTE_ADDR},id:5000134

<LocationMatch "/wp-login.php">
    # Setup brute force detection.

    # React if block flag has been set.

    SecRule user:bf_block "@gt 0" "deny,status:401,log,id:5000135,msg:'ip address blocked for 60 minutes, more than 5 login attempts in 15 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/900,id:5000137"
    SecRule ip:bf_counter "@gt 5" "t:none,setvar:user.bf_block=1,expirevar:user.bf_block=3600,setvar:ip.bf_counter=0"

</LocationMatch>
ErrorDocument 401 default
 
This section is where it counts the failed login attempts. I changed it from 180 seconds (3 minutes) to 900 seconds (15 minutes). Certainly a hacker trying to brute force your WP site would do 5 failed logins within 3 minutes, but just in case they're slow to type.

Yes, I originally had it set to 900, but lowered it back to 180 in an attempt to make sure that the CSF block would get triggered.

LF_MODSEC is set at 5.

So I have everything set the same as you, but it does not appear to be working. I still wonder if the NginxCP plugin can be interfering somehow?

The IP that was recently accessing wp-login.php is now no longer doing so. But when I look in CSF for the blocked IP, there is no entry. I will keep monitoring it and see if things change.

I just wanted to have someone look at it for a sanity check. :p
Thanks for your help
 
Lowering it to 180 does just the opposite, setting it to a higher number will make sure CSF will get triggered. That number is how many seconds ModSec will count failed login attempts. So setting it to 3 minutes, rather than 15 minutes means a hacker can fail up to 4 logins every 3 minutes without ever triggering CSF to block them. They wouldn't know that of course, but that's what the setting means.
You don't have to wait on a hacker to test your ModSec script. I tested mine by just failing logins until it blocked me. Then remoted into a system at another location to get into CSF and unblock me. I kept doing that until I was happy with the settings.
 
Lowering it to 180 does just the opposite, setting it to a higher number will make sure CSF will get triggered.

Ahhh... I misread that.
OK, I've set it back to 900 now.

I would do the test myself, like you did. But then I would either have to physically go to another location to unblock it, or I suppose I could have KH support do it for me.

Thanks so much for your help!
 
Lowering it to 180 does just the opposite, setting it to a higher number will make sure CSF will get triggered. That number is how many seconds ModSec will count failed login attempts. So setting it to 3 minutes, rather than 15 minutes means a hacker can fail up to 4 logins every 3 minutes without ever triggering CSF to block them. They wouldn't know that of course, but that's what the setting means.
You don't have to wait on a hacker to test your ModSec script. I tested mine by just failing logins until it blocked me. Then remoted into a system at another location to get into CSF and unblock me. I kept doing that until I was happy with the settings.

Josh -
I still cannot get this to work. I have the script set at your suggested settings, and LF_MODSEC set at 5.
The only thing I can think of is that I am running a different version of WHM than you?
I am on WHM 54.0 (build 19), Centos 7.2, and Apache 2.4.18.
Anyway, I think I will give it up for now, and come back to this in the future.
 
Sorry to hear that. I don't recall doing anything out of the ordinary to get it working. WHM version shouldn't matter since all that's required is ModSec and CSF.
@KH-Jonathan is this something support might help with?
 
Sorry to hear that. I don't recall doing anything out of the ordinary to get it working. WHM version shouldn't matter since all that's required is ModSec and CSF.
@KH-Jonathan is this something support might help with?

Our support of ModSec goes so far as turning it on/off. We don't delve into rules because they have to be tailored to your site. It's easy to get them going wild blocking you for things you shouldn't be getting blocked for due to a slightly misconfigured rule, new plugin, etc. that it doesn't account for.
 
I agree. Understandable.
Sorry, @WebEndev without getting in there myself I can't imagine what the issue could be. I'll maybe wipe out my configuration and try it from scratch to see if there was anything I missed for you.
 
Came back here to add my rules to a new dedi. Just a small update.

Paths have changed with newer versions of cPanel so it's easiest just to apply the rule in: WHM »Security Center »ModSecurity™ Tools » Rules List (button top right) » Edit Rules (button top right).

All I had to do was copy the script from earlier in this discussion, into the Rules text-area, check that "Deploy and Restart Apache", click save.

To test I remoted into a client's network (so I wouldn't block my network), failed a login 5 times, and was happy to see I was blocked.

Have an issue though, after getting blocked from testing I removed the entry in CSF to unblock the IP, it did unblock the IP but as soon as I tried to login to WP again it immediately blocked me before processing the login. I'm sure it's something simple in the rules. Probably mod_sec still keeping count of the failed logins and triggering before letting me in again. I'll work on that another day, and by that I mean I'll forget about it then run into the issue at some point and wonder why. :p
 
Top