Use modsecurity / CSF to block all common cms logins?

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
Good morning.

One of my cPanel servers hosts only a few domains owned by the same client, none of which use a CMS. All of the sites are hand-coded in PHP.

We get an absurd number of requests on non-existent default CMS login pages (wp-login.php, for example). I have to assume that they're all malicious, so I'd like to use modsecurity and CSF to temp block every IP address that attempts to access those pages even once. There's no legitimate reason why anyone would be trying to access them, and we have no plans to ever implement a CMS on this server; so I figure I may as well block them at the firewall.

First question: Is this a bad idea?

Second question: If it's not a bad idea, which pages should I block? I personally don't use CMSs except for one WP installation on another server, so I really have little knowledge of them other than that WordPress seems to be the most popular.

Third question: Assuming this isn't a horrid idea, any suggestions for the rule itself would be appreciated. I have little experience or familiarity with writing custom rules, so I'd rather ask than break something.

Thanks,

Richard
 

GOT

Get Proactive!
PartnerNOC
Apr 8, 2003
1,542
207
343
Chesapeake, VA
cPanel Access Level
DataCenter Provider
I don't necessarily think it's a bad idea however writing and maintaining all those rules is going to consume a lot of your time including the research into specifically which files to block.

Serving a 404 code is pretty lightweight to the server. So having some of these is not really a big deal and since you're not actually using it poses almost no risk whatsoever.

If it annoys you what I would suggest is using the 404 block rule in csf. Say after 15 404 errors then csf will temp block the ip.

Settings for this are in the csf.conf. Search on 404 I dont recall the exact wording of it but it's easy to set up.

Don't set it too low otherwise you may get some false positives from your clients or developers.
 
  • Like
Reactions: GeekOnTheHill

rpvw

Well-Known Member
Jul 18, 2013
1,088
446
113
Spain
cPanel Access Level
Root Administrator
This might get you started: blog.pheonixsolutions.com/block-wordpress-login-attacks-csf/
 
  • Like
Reactions: GeekOnTheHill

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
I don't necessarily think it's a bad idea however writing and maintaining all those rules is going to consume a lot of your time including the research into specifically which files to block.

Serving a 404 code is pretty lightweight to the server. So having some of these is not really a big deal and since you're not actually using it poses almost no risk whatsoever.

If it annoys you what I would suggest is using the 404 block rule in csf. Say after 15 404 errors then csf will temp block the ip.

Settings for this are in the csf.conf. Search on 404 I dont recall the exact wording of it but it's easy to set up.

Don't set it too low otherwise you may get some false positives from your clients or developers.
Thanks.

My reason for considering an outright block is that a person attempting to access a well-known but non-existent login page is almost certainly a malicious actor, and blocking them completely would prevent them from trying any other tricks from that IP for the duration of the block.

Of course, a targeted human attacker could always use a different IP and avoid accessing that particular page on subsequent tries; but most of these attacks are scripted, and I doubt that too many robots have the presence of mind to figure out what's going on when they're blocked.

Richard
 

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator

fuzzylogic

Well-Known Member
Nov 8, 2014
136
78
28
cPanel Access Level
Root Administrator
1). Definitely not a bad idea.
These IPs are revealing to us they most likely hacked sites/servers (also likely part of a group of compromised servers with a centralized control)
An IP running dictionary attacks wp-login.php today may very well be running attacks on a newly discovered, unpatched ssh vulnerability tomorrow.
With that in mind I suggest you consider permanent blocking in csf.deny rather than temp blocking.
CSF settings for this can be found in another post at...
modsec rule 942100 not being blocked, status 200

2). Pages to block.
Code:
Wordpress
domain.com/wp-login.php

Wordpress xmlrpc
domain.com/xmlrpc.php

Joomla
domain.com/administrator

Drupal
domain.com/user/login

Magento 1
domain.com/index.php/admin/

Magento 2
domain.com/admin
3). If you are certain you do not have (and will not have in the future) any URIs on your server with the phrases (login or xmlrpc or admin) then the following rule should suit.
Code:
# Deny POST to some default CMS login pages
SecRule REQUEST_METHOD "@streq POST" \
    "msg:'Deny POST to CMS login pages rule is being hit',\
    id:19000001,\
    phase:1,\
    t:none,\
    log,\
    auditlog,\
    deny,\
    status:403,\
    chain"
    SecRule REQUEST_FILENAME "@pm login xmlrpc admin" \
        "t:none"
4). I don't recommend using the CSF 404 Block Rule set any lower than 100-200 or something as simple as a missing theme image can lock out site visitors.

5). The 2 CSF custom regex rules linked to above both do only temp blocks (1 hour) on (possibly) limited ports 80, 443
Code:
return ("Failed WordPress login from",$1,"wordpress","5","80,443","3600");
If you choose to do things that way (entirely in csf custom regex) read the example in /etc/csf/regex.custom.pm
to learn how to block permanently on all ports.
 
Last edited:
  • Like
Reactions: GeekOnTheHill

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
1). Definitely not a bad idea.
These IPs are revealing to us they most likely hacked sites/servers (also likely part of a group of compromised servers with a centralized control)
An IP running dictionary attacks wp-login.php today may very well be running attacks on a newly discovered, unpatched ssh vulnerability tomorrow.
With that in mind I suggest you consider permanent blocking in csf.deny rather than temp blocking.
CSF settings for this can be found in another post at...
modsec rule 942100 not being blocked, status 200

2). Pages to block.
Code:
Wordpress
domain.com/wp-login.php

Wordpress xmlrpc
domain.com/xmlrpc.php

Joomla
domain.com/administrator

Drupal
domain.com/user/login

Magento 1
domain.com/index.php/admin/

Magento 2
domain.com/admin
3). If you are certain you do not have (and will not have in the future) any URIs on your server with the phrases (login or xmlrpc or admin) then the following rule should suit.
Code:
# Deny POST to some default CMS login pages
SecRule REQUEST_METHOD "@streq POST" \
    "msg:'Deny POST to CMS login pages rule is being hit',\
    id:19000001,\
    phase:1,\
    t:none,\
    log,\
    auditlog,\
    deny,\
    status:403,\
    chain"
    SecRule REQUEST_FILENAME "@pm login xmlrpc admin" \
        "t:none"
4). I don't recommend using the CSF 404 Block Rule set any lower than 100-200 or something as simple as a missing theme image can lock out site visitors.

5). The 2 CSF custom regex rules linked to above both do only temp blocks (1 hour) on (possibly) limited ports 80, 443
Code:
return ("Failed WordPress login from",$1,"wordpress","5","80,443","3600");
If you choose to do things that way (entirely in csf custom regex) read the example in /etc/csf/regex.custom.pm
to learn how to block permanently on all ports.
Thank you very much.

I'm wary of permanently blocking an IP because it may be a dynamic address or a public proxy. But than again, I believe the default PERMBLOCK is actually only 24 hours anyway.

Something like this, with certain safeguards built in, might actually be a basis for a useful honeypot to generate a rotating malicious IP RBL.

Richard
 

fuzzylogic

Well-Known Member
Nov 8, 2014
136
78
28
cPanel Access Level
Root Administrator
I think you are misunderstanding LF_PERMBLOCK.
It is a way to add a repeat temporary block offender to the csf.deny file.
If LF_PERMBLOCK_COUNT temp blocks in LF_PERMBLOCK_INTERVAL period then add IP to csf.deny.

csf.deny is limited to the number of IPs set in DENY_IP_LIMIT.
After that number is achieved the oldest entry is deleted when a new one is added.
The recommended max No. for DENY_IP_LIMIT is 1000.
I have seen a turnover time of 3 months with the limit set at 1000

Back to the logic of what you are doing here.
Your objectives can be to...
1) Restrict access by offending IPs so as to preserve server resources.
2) Restrict access by offending IPs so as to prevent those IPs carrying out hack attempts.
3) Both of the above.

Temp blocks achieve #1 and block to login attempts which GOT pointed out are no threat to your server.
They do not achieve #2.

Perm blocks achieve #1 and #2, but as you point out may block public proxies or dynamic IPs

You just have to work out which compromise is most important to you on this server.
 
  • Like
Reactions: GeekOnTheHill

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
I think you are misunderstanding LF_PERMBLOCK.
It is a way to add a repeat temporary block offender to the csf.deny file.
If LF_PERMBLOCK_COUNT temp blocks in LF_PERMBLOCK_INTERVAL period then add IP to csf.deny.

csf.deny is limited to the number of IPs set in DENY_IP_LIMIT.
After that number is achieved the oldest entry is deleted when a new one is added.
The recommended max No. for DENY_IP_LIMIT is 1000.
I have seen a turnover time of 3 months with the limit set at 1000

Back to the logic of what you are doing here.
Your objectives can be to...
1) Restrict access by offending IPs so as to preserve server resources.
2) Restrict access by offending IPs so as to prevent those IPs carrying out hack attempts.
3) Both of the above.

Temp blocks achieve #1 and block to login attempts which GOT pointed out are no threat to your server.
They do not achieve #2.

Perm blocks achieve #1 and #2, but as you point out may block public proxies or dynamic IPs

You just have to work out which compromise is most important to you on this server.
Okay, thanks for clarifying that. I'll have to look up the logs and do some math to come up with something reasonable. I don't want to forever block "innocent" IPs that just happened to be used by a malicious individual on a given day, but I would like to completely restrict those IPs for enough time for the malicious actor to move on. I'm definitely going to have to give this some thought before implementing it.

Thanks again,

Richard
 

fuzzylogic

Well-Known Member
Nov 8, 2014
136
78
28
cPanel Access Level
Root Administrator
As a matter of interest, if you research the owners of IPs behaving badly I would be interested in the numbers/percentages you find that are in fact listed public proxies or owned by telcos (possibly dynamic).
In my experience less than 5 in a 1000 were owned by telcos (at least from countries I am interested in allowing)
I have never checked against public proxy lists.
 

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
As a matter of interest, if you research the owners of IPs behaving badly I would be interested in the numbers/percentages you find that are in fact listed public proxies or owned by telcos (possibly dynamic).
In my experience less than 5 in a 1000 were owned by telcos (at least from countries I am interested in allowing)
I have never checked against public proxy lists.
Okay; although I must say, I get hundreds of them a day between failed WP, WHM, and SSH login attempts, so I can't promise anything.

Some months, the number one page served is the 404 page; and when I check the raw logs, they're all CMS login attempts. The client actually asked me about that once, thinking I must have had a bad link somewhere on the site. But they were all from miscreants trying to access non-existent login pages.

Richard
 

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
Sorry I disappeared for a while. I had a few high-priority jobs. One was especially interesting: coding a custom blog from scratch. It wasn't all that hard. It was just something I hadn't done before.

Anyway, back to the original topic. I decided last night to at least get started on this project. I resurrected my dormant AbuseIPDB account, created some keys, and coded a honeypot page. I made entries in .htaccess to redirect all the hits on wp-login.php, xmlrpc.php, admin.php, and login.php to the honeypot page.

What the honeypot does is stash the information about every request for the page in a database, checks that database to prevent reporting the same IP more than once every 15 minutes (that's an AbuseIPDB rule), and sends the report to AbuseIPDB. Of course, the database also is a record of all the events that I can use for whatever else I decide to do with it.

I installed the script on a handful of sites last night. Here's who it's caught so far:

GeekOnTheHill - AbuseIPDB User Profile

As for what I can do with the information on my end, I have a lot of options to consider. Because these IP's tend to be ephemeral, something immediate and short-term would be nice, possibly with the ability to flag repeat offenders for longer-term banishment. The quick-and-dirty way would be to use sudo or ssh2 to manually add the IP to iptables. I'm thinking about more elegant solutions, though.

I don't want to block access to those pages completely. I'd rather use them as honeypots, for whatever good it does. That part is accomplished. Now I just have to decide what to do locally with the data now that I'm collecting it.

Richard

EDIT:

Maybe now would be a good time to use a REGEX, since all the abused URLs wind up on the same page and it's easy to add new ones in .htaccess if I want to. Any IP that accesses the honeypot would get denied for a time. That's probably the easiest way.
 
Last edited:

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
As a matter of interest, if you research the owners of IPs behaving badly I would be interested in the numbers/percentages you find that are in fact listed public proxies or owned by telcos (possibly dynamic).
In my experience less than 5 in a 1000 were owned by telcos (at least from countries I am interested in allowing)
I have never checked against public proxy lists.
Please see Post 15.

Richard
 

GeekOnTheHill

Active Member
Feb 16, 2015
25
5
3
cPanel Access Level
Root Administrator
I think the solution turned out to be a simple one: Just include a proper 401 page at the end of the honeypot, and then use LF_APACHE_401 and LF_APACHE_401_PERM to do the blocking.

Yeah, I know there's supposed to be an authentication failure for a 401. But these are bad bots and a handful of human miscreants. If they want to sue me for giving them a 401 rather than a 403, then so be it.

Richard