-
-
Save jaygooby/3502143639e09bb694e9c0f3c6203949 to your computer and use it in GitHub Desktop.
# log4j jndi exploit CVE-2021-44228 filter | |
# Save this file as /etc/fail2ban/filter.d/log4j-jndi.conf | |
# then copy and uncomment the [log4j-jndi] section | |
# to /etc/fail2ban/jail.local | |
# | |
# jay@gooby.org | |
# https://jay.gooby.org/2021/12/13/a-fail2ban-filter-for-the-log4j-cve-2021-44228 | |
# https://gist.github.com/jaygooby/3502143639e09bb694e9c0f3c6203949 | |
# Thanks to https://gist.github.com/kocour for a better regex | |
# | |
# Bad actors trying to exploit log4j - instaban them with | |
# this in your /etc/fail2ban/jail.local | |
# | |
# We're using maxretry = 1 | |
# because we know that they're a bad actor... | |
# | |
# [log4j-jndi] | |
# maxretry = 1 | |
# enabled = true | |
# port = 80,443 | |
# logpath = /path/to/your/*access.log | |
[Definition] | |
failregex = (?i)^<HOST> .* ".*\$.*(7B|\{).*(lower:)?.*j.*n.*d.*i.*:.*".*?$ |
I've been rechecking with my own logs (last 10 million entries) and I've had far better matches and no false positives with this rule:
failregex = (?i)^<HOST> .* ".*\$.*(7B|\{).*(lower:)?.*j.*n.*d.*i.*:.*".*?$
which will case-insensitive check the URL, referer and user-agent too (I had a lot of regular URL requests but with jndi:
referers).
This matches against a requirement for at least a leading $
followed by {
, (regular or escaped) followed by jndi:
(but allowing for extra ${
and so on, in between).
You should verify this yourself against your own logs. Most importantly, check for false positives by looking at the Missed line(s)
section:
sudo fail2ban-regex --print-all-matched --print-all-missed /path/to/access.log /etc/fail2ban/filter.d/log4j-jndi.conf |less
Thanks @jaygooby - I'll do some testing.
I just added
filter = log4j-jndi
to the section in jail.local
It should also match (URL encoded) requests like:
/?a=%24%7Bjndi%3Aldap%3A/
Tested:
failregex = (?i)^<HOST> .* ".*(\$|%%24).*(\{|%%7B).*(lower:)?.*j.*n.*d.*i.*(:|%%3A).*".*?$
In any case, there is something missing in the "jail" but I don't do what?
and I don't know what exactly to put in failregex as many people don't have the same one.
log4j-jndi.conf :
`
log4j jndi exploit CVE-2021-44228 filter
Save this file as /etc/fail2ban/filter.d/log4j-jndi.conf
then copy and uncomment the [log4j-jndi] section
to /etc/fail2ban/jail.local
jay@gooby.org
https://jay.gooby.org/2021/12/13/a-fail2ban-filter-for-the-log4j-cve-2021-44228
https://gist.github.com/jaygooby/3502143639e09bb694e9c0f3c6203949
Thanks to https://gist.github.com/kocour for a better regex
Bad actors trying to exploit log4j - instaban them with
this in your /etc/fail2ban/jail.local
We're using maxretry = 1
because we know that they're a bad actor...
[log4j-jndi]
maxretry = 1
enabled = true
port = 80,443
logpath = /path/to/your/*access.log
[Definition]
failregex = (?i)^ .* ".$.(7B|{).*(lower:)?.*j.n.d.i.:.".?$`
jail.local :
LOG4J HTTP/HTTPS [log4j-jndi] maxretry = 1 enabled = true filter = log4j-jndi port = 80,443 logpath = /var/www/neko-world/log/requests.log Ban IP and report to AbuseIPDB for LOG4J action = %(action_)s %(action_abuseipdb)s[abuseipdb_category="3,4,6,10,15,18,20,22"]
systemctl status :
` fail2ban.service - Fail2Ban Service
Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2021-12-18 21:32:26 CET; 2s ago
Docs: man:fail2ban(1)
Process: 28867 ExecStop=/usr/bin/fail2ban-client stop (code=exited, status=0/SUCCESS)
Process: 31391 ExecStart=/usr/bin/fail2ban-server -xf start (code=exited, status=255)
Process: 31389 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS)
Main PID: 31391 (code=exited, status=255)
déc. 18 21:32:26 neko-world.local systemd[1]: Starting Fail2Ban Service...
déc. 18 21:32:26 neko-world.local systemd[1]: Started Fail2Ban Service.
déc. 18 21:32:26 neko-world.local fail2ban-server[31391]: 2021-12-18 21:32:26,609 fail2ban [31391]: ERROR Failed during configuration: Have not found any log file for log4j-jndi jail
déc. 18 21:32:26 neko-world.local fail2ban-server[31391]: 2021-12-18 21:32:26,623 fail2ban [31391]: ERROR Async configuration of server failed
déc. 18 21:32:26 neko-world.local systemd[1]: fail2ban.service: Main process exited, code=exited, status=255/n/a
déc. 18 21:32:26 neko-world.local systemd[1]: fail2ban.service: Failed with result 'exit-code'.`
You should debug your jail.local. Did you set a valid log path?
You could post your log4j section here for help if you would like to.
Do we need to extend the regex pattern for the next CVE? CVE-2021-45105
https://thehackernews.com/2021/12/apache-issues-3rd-patch-to-fix-new-high.html
Any ideas?
I debugged my jail.local and the problem is log4j
Just collating in a single comment the changes I chose/had to make to get this working for me, mostly from the comments above.
# log4j jndi exploit CVE-2021-44228 filter
# Save this file as /etc/fail2ban/filter.d/log4j-jndi.conf
# then copy and uncomment the [log4j-jndi] section
# to /etc/fail2ban/jail.local
#
# jay@gooby.org
# https://jay.gooby.org/2021/12/13/a-fail2ban-filter-for-the-log4j-cve-2021-44228
# https://gist.github.com/jaygooby/3502143639e09bb694e9c0f3c6203949
# Thanks to https://gist.github.com/kocour for a better regex
#
# Bad actors trying to exploit log4j - instaban them with
# this in your /etc/fail2ban/jail.local
#
# We're using maxretry = 1
# because we know that they're a bad actor...
#
# [log4j-jndi]
# maxretry = 1
# filter = log4j-jndi
# action = your_actions_here
# enabled = true
# port = 80,443
# logpath = /path/to/your/*access.log
[Definition]
failregex = (?i)^<HOST> .* ".*(\$|%%24).*(\{|%%7B).*(lower:)?.*j.*n.*d.*i.*(:|%%3A).*".*?$
ignoreregex =
I chose to use the regex suggested by @ursut. Thanks for sharing this @jaygooby!
I found the problem there is no backend your jail says it doesn't find the logs so I point to the logs but need to put a backend
[log4j-jndi]
maxretry = 1
enabled = true
filter = log4j-jndi
port = 80,443
logpath = /var/log/httpd/*access.log
backend = %(syslog_backend)s
# Ban IP and report to AbuseIPDB for LOG4J
action = %(action_)s
%(action_abuseipdb)s[abuseipdb_category="3,4,6,15,18,20,22"]
@kocour 😆 agreed on both points!