Log4j Vulnerability: Impact & Detection

By now, you’ve likely heard of the latest Java-based vulnerability CVE-2021-44228, a critical zero-day vulnerability related to Apache Log4j Java logging library.

Affecting everything from enterprise software to web applications and well-known consumer products, CVE-2021-44228 impacts any organization using the Apache Log4j framework including Apache Struts2, Apache Solr, Apache Druid, Apache Flink, and others.

Published on GitHub on December 9, 2021, the first proof-of-concept exploit enables unauthenticated remote code execution resulting in a complete system takeover. On December 10, 2021, public and private cyber intelligence groups around the world reported the first usage of the exploit, identifying massive scanning from multiple hosts for servers using vulnerable versions of Apache Log4j. Receiving a rating of 10 on the CVSS scale, Apache has already released Log4j 2.15.0 to address the maximum severity rating. However, given the pervasive nature of the Java logging library and multiple points of entry (the extent of which is not known yet), Log4j presents significant challenges for security teams to address potentially numerous points of entry.

While all organizations are encouraged to quickly act on Apache’s latest release, several security operations teams and researchers across the globe have already started working on open-source projects that appear to use Log4j by default. The list below is likely incomplete at this time; however, it begins to highlight the breadth of systems that can be affected:

  • Elasticsearch
  • Grails
  • Hadoop
  • Kafka
  • Kibana
  • Solr
  • Spark
  • Struts
  • Tapestry
  • Wicket

Log4j impact on manufacturers and components as listed below;

  • Apple
  • Tencent
  • Steam
  • Twitter
  • Baidu
  • NetEase
  • CloudFlare
  • Amazon
  • Tesla
  • IBM Qradar SIEM
  • PaloAlto Panorama
  • Redis
  • ghidra
  • ghidra server
  • Minecraft
  • UniFi

Like Heartbleed and Shellshock, we suspect the number of vulnerable environments to grow over the coming weeks. The list above is available on  GitHub and may be updated in real-time as new systems are identified.

Detecting Log4j RCE Exploitation

The following commands and rules can be used to search for exploitation attempts against vulnerable versions of log4j:

This command searches for exploitation attempts in uncompressed files in folder /var/log and all subfolders

sudo egrep -i -r '\$\{jndi:(ldap[s]?|rmi|dns):/[^\n]+' /var/log

As used below, we could see a scan attempt from 167.172.44.255, 45.83.64.1 to one of our test webservers hosted on the cloud.

This command searches for exploitation attempts in compressed files in folder /var/log and all subfolders

sudo find /var/log -name *.gz -print0 | xargs -0 zgrep -E -i '\${jndi:(ldap[s]?|rmi|dns):/[^\n]+'

The following YARA rules from Strelka were updated recently

rule XPL_Log4j_CallBackDomain_IOCs_Dec21_1 {\n+ meta:\n+ description = "Detects IOCs found in Log4Shell incidents that indicate exploitation attempts of CVE-2021-44228"\n+ author = "Florian Roth"\n+ reference = "https://gist.github.com/superducktoes/9b742f7b44c71b4a0d19790228ce85d8"\n+ date = "2021-12-12"\n+ score = 60\n+ strings:\n+ $xr1 = /\b(ldap|rmi):\/\/([a-z0-9\.]{1,16}\.bingsearchlib\.com|[a-z0-9\.]{1,40}\.interact\.sh|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}):[0-9]{2,5}\/([aZ]|ua|Exploit|callback|[0-9]{10}|http443useragent|http80useragent)\b/\n+ condition:\n+ 1 of them\n+}
rule EXPL_JNDI_Exploit_Patterns_Dec21_1 {\n+ meta:\n+ description = "Detects JNDI Exploit Kit patterns in files"\n+ author = "Florian Roth"\n+ reference = "https://github.com/pimps/JNDI-Exploit-Kit"\n+ date = "2021-12-12"\n+ score = 60\n+ strings:\n+ $ = "/Basic/Command/Base64/"\n+ $ = "/Basic/ReverseShell/"\n+ $ = "/Basic/TomcatMemshell"\n+ $ = "/Basic/JettyMemshell"\n+ $ = "/Basic/WeblogicMemshell"\n+ $ = "/Basic/JBossMemshell"\n+ $ = "/Basic/WebsphereMemshell"\n+ $ = "/Basic/SpringMemshell"\n+ $ = "/Deserialization/URLDNS/"\n+ $ = "/Deserialization/CommonsCollections1/Dnslog/"\n+ $ = "/Deserialization/CommonsCollections2/Command/Base64/"\n+ $ = "/Deserialization/CommonsBeanutils1/ReverseShell/"\n+ $ = "/Deserialization/Jre8u20/TomcatMemshell"\n+ $ = "/TomcatBypass/Dnslog/"\n+ $ = "/TomcatBypass/Command/"\n+ $ = "/TomcatBypass/ReverseShell/"\n+ $ = "/TomcatBypass/TomcatMemshell"\n+ $ = "/TomcatBypass/SpringMemshell"\n+ $ = "/GroovyBypass/Command/"\n+ $ = "/WebsphereBypass/Upload/"\n+ condition:\n+ 1 of them\n+}
rule EXPL_Log4j_CVE_2021_44228_JAVA_Exception_Dec21_1 {\n+ meta:\n+ description = "Detects exceptions found in server logs that indicate an exploitation attempt of CVE-2021-44228"\n+ author = "Florian Roth"\n+ reference = "https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b"\n+ date = "2021-12-12"\n+ score = 60\n+ strings:\n+ $xa1 = "header with value of BadAttributeValueException: "\n+ \n+ $sa1 = ".log4j.core.net.JndiManager.lookup(JndiManager"\n+ $sa2 = "Error looking up JNDI resource"\n+ condition:\n+ $xa1 or all of ($sa*)\n+}
rule EXPL_Log4j_CVE_2021_44228_Dec21_Soft {\n meta:\n@@ -5,12 +66,38 @@\n author = "Florian Roth"\n reference = "https://twitter.com/h113sdx/status/1469010902183661568?s=20"\n date = "2021-12-10"\n- score = 70\n+ modified = "2021-12-12"\n+ score = 60\n strings:\n- $x1 = "${jndi:ldap:/"\n- $x2 = "${jndi:rmi:/"\n- $x3 = "${jndi:ldaps:/"\n- $x4 = "${jndi:dns:/"\n+ $ = "${jndi:ldap:/"\n+ $ = "${jndi:rmi:/"\n+ $ = "${jndi:ldaps:/"\n+ $ = "${jndi:dns:/"\n+ $ = "${jndi:iiop:/"\n+ $ = "${jndi:http:/"\n+ $ = "${jndi:nis:/"\n+ $ = "${jndi:nds:/"\n+ $ = "${jndi:corba:/"\n+ condition:\n+ 1 of them\n+}
rule EXPL_Log4j_CVE_2021_44228_Dec21_OBFUSC {\n+ meta:\n+ description = "Detects obfuscated indicators in server logs that indicate an exploitation attempt of CVE-2021-44228"\n+ author = "Florian Roth"\n+ reference = "https://twitter.com/h113sdx/status/1469010902183661568?s=20"\n+ date = "2021-12-12"\n+ score = 60\n+ strings:\n+ $x1 = "$%7Bjndi:"\n+ $x2 = "%2524%257Bjndi"\n+ $x3 = "%2F%252524%25257Bjndi%3A"\n+ $x4 = "${jndi:${lower:"\n+ $x5 = "${::-j}${"\n+ $x6 = "${${env:BARFOO:-j}"\n+ $x7 = "${::-l}${::-d}${::-a}${::-p}"\n+ $x8 = "${base64:JHtqbmRp"\n condition:\n 1 of them\n }\n@@ -21,9 +108,10 @@\n author = "Florian Roth"\n reference = "https://twitter.com/h113sdx/status/1469010902183661568?s=20"\n date = "2021-12-10"\n+ modified = "2021-12-12"\n score = 80\n strings:\n- $x1 = /\$\{jndi:(ldap|ldaps|rmi|dns):\/[\/]?[a-z-\.0-9]{3,120}:[0-9]{2,5}\/[a-zA-Z\.]{1,32}\}/\n+ $x1 = /\$\{jndi:(ldap|ldaps|rmi|dns|iiop|http|nis|nds|corba):\/[\/]?[a-z-\.0-9]{3,120}:[0-9]{2,5}\/[a-zA-Z\.]{1,32}\}/\n $fp1r = /(ldap|rmi|ldaps|dns):\/[\/]?(127\.0\.0\.1|192\.168\.|172\.[1-3][0-9]\.|10\.)/\n condition:\n $x1 and not 1 of ($fp)\n@@ -55,9 +143,10 @@\n author = "Florian Roth"\n reference = "https://github.com/flypig5211/JNDIExploit"\n date = "2021-12-10"\n+ modified = "2021-12-12"\n score = 70\n strings:\n- $xr1 = /ldap:\/\/[a-zA-Z0-9\.]{7,80}:[0-9]{2,5}\/(Basic\/Command\/Base64|Basic\/ReverseShell|Basic\/TomcatMemshell|Basic\/JBossMemshell|Basic\/WebsphereMemshell|Basic\/SpringMemshell|Basic\/Command|Deserialization\/CommonsCollectionsK|Deserialization\/CommonsBeanutils|Deserialization\/Jre8u20\/TomcatMemshell|Deserialization\/CVE_2020_2555\/WeblogicMemshell|TomcatBypass|GroovyBypass|WebsphereBypass)\//\n+ $xr1 = /(ldap|ldaps|rmi|dns|iiop|http|nis|nds|corba):\/\/[a-zA-Z0-9\.]{7,80}:[0-9]{2,5}\/(Basic\/Command\/Base64|Basic\/ReverseShell|Basic\/TomcatMemshell|Basic\/JBossMemshell|Basic\/WebsphereMemshell|Basic\/SpringMemshell|Basic\/Command|Deserialization\/CommonsCollectionsK|Deserialization\/CommonsBeanutils|Deserialization\/Jre8u20\/TomcatMemshell|Deserialization\/CVE_2020_2555\/WeblogicMemshell|TomcatBypass|GroovyBypass|WebsphereBypass)\//\n condition:\n filesize < 100MB and $xr1\n }\n@@ -78,7 +167,9 @@\n $ = "$%7blower:"\n $ = "$%7bupper:"\n $ = "%24%7bjndi:"\n- $ = "/$%7bjndi:"\n+ $ = "$%7Blower:"\n+ $ = "$%7Bupper:"\n+ $ = "%24%7Bjndi:"\n condition:\n 1 of them\n }\n'}} /var/log/messages:Dec 14 07:13:54 secon salt-minion: [INFO ] {'/opt/so/conf/strelka/rules/signature-base/expl_log4j_cve_2021_44228.yar': {'diff': '--- \n+++ \n@@ -20,28 +20,30 @@\n date = "2021-12-12"\n score = 60\n strings:\n- $ = "/Basic/Command/Base64/"\n- $ = "/Basic/ReverseShell/"\n- $ = "/Basic/TomcatMemshell"\n- $ = "/Basic/JettyMemshell"\n- $ = "/Basic/WeblogicMemshell"\n- $ = "/Basic/JBossMemshell"\n- $ = "/Basic/WebsphereMemshell"\n- $ = "/Basic/SpringMemshell"\n- $ = "/Deserialization/URLDNS/"\n- $ = "/Deserialization/CommonsCollections1/Dnslog/"\n- $ = "/Deserialization/CommonsCollections2/Command/Base64/"\n- $ = "/Deserialization/CommonsBeanutils1/ReverseShell/"\n- $ = "/Deserialization/Jre8u20/TomcatMemshell"\n- $ = "/TomcatBypass/Dnslog/"\n- $ = "/TomcatBypass/Command/"\n- $ = "/TomcatBypass/ReverseShell/"\n- $ = "/TomcatBypass/TomcatMemshell"\n- $ = "/TomcatBypass/SpringMemshell"\n- $ = "/GroovyBypass/Command/"\n- $ = "/WebsphereBypass/Upload/"\n- condition:\n- 1 of them\n+ $x01 = "/Basic/Command/Base64/"\n+ $x02 = "/Basic/ReverseShell/"\n+ $x03 = "/Basic/TomcatMemshell"\n+ $x04 = "/Basic/JettyMemshell"\n+ $x05 = "/Basic/WeblogicMemshell"\n+ $x06 = "/Basic/JBossMemshell"\n+ $x07 = "/Basic/WebsphereMemshell"\n+ $x08 = "/Basic/SpringMemshell"\n+ $x09 = "/Deserialization/URLDNS/"\n+ $x10 = "/Deserialization/CommonsCollections1/Dnslog/"\n+ $x11 = "/Deserialization/CommonsCollections2/Command/Base64/"\n+ $x12 = "/Deserialization/CommonsBeanutils1/ReverseShell/"\n+ $x13 = "/Deserialization/Jre8u20/TomcatMemshell"\n+ $x14 = "/TomcatBypass/Dnslog/"\n+ $x15 = "/TomcatBypass/Command/"\n+ $x16 = "/TomcatBypass/ReverseShell/"\n+ $x17 = "/TomcatBypass/TomcatMemshell"\n+ $x18 = "/TomcatBypass/SpringMemshell"\n+ $x19 = "/GroovyBypass/Command/"\n+ $x20 = "/WebsphereBypass/Upload/"\n+\n+ $fp1 = ") and not 1 of ($fp)\n }\n \n rule EXPL_Log4j_CVE_2021_44228_JAVA_Exception_Dec21_1 {\n@@ -66,20 +68,22 @@\n author = "Florian Roth"\n reference = "https://twitter.com/h113sdx/status/1469010902183661568?s=20"\n date = "2021-12-10"\n- modified = "2021-12-12"\n- score = 60\n- strings:\n- $ = "${jndi:ldap:/"\n- $ = "${jndi:rmi:/"\n- $ = "${jndi:ldaps:/"\n- $ = "${jndi:dns:/"\n- $ = "${jndi:iiop:/"\n- $ = "${jndi:http:/"\n- $ = "${jndi:nis:/"\n- $ = "${jndi:nds:/"\n- $ = "${jndi:corba:/"\n- condition:\n- 1 of them\n+ modified = "2021-12-13"\n+ score = 60\n+ strings:\n+ $x01 = "${jndi:ldap:/"\n+ $x02 = "${jndi:rmi:/"\n+ $x03 = "${jndi:ldaps:/"\n+ $x04 = "${jndi:dns:/"\n+ $x05 = "${jndi:iiop:/"\n+ $x06 = "${jndi:http:/"\n+ $x07 = "${jndi:nis:/"\n+ $x08 = "${jndi:nds:/"\n+ $x09 = "${jndi:corba:/"\n+\n+ $fp1 = ") and not 1 of ($fp)\n }\n \n rule EXPL_Log4j_CVE_2021_44228_Dec21_OBFUSC {\n@@ -88,6 +92,7 @@\n author = "Florian Roth"\n reference = "https://twitter.com/h113sdx/status/1469010902183661568?s=20"\n date = "2021-12-12"\n+ modified = "2021-12-13"\n score = 60\n strings:\n $x1 = "$%7Bjndi:"\n@@ -98,8 +103,10 @@\n $x6 = "${${env:BARFOO:-j}"\n $x7 = "${::-l}${::-d}${::-a}${::-p}"\n $x8 = "${base64:JHtqbmRp"\n- condition:\n- 1 of them\n+\n+ $fp1 = ") and not 1 of ($fp)\n }\n \n rule EXPL_Log4j_CVE_2021_44228_Dec21_Hard {\n@@ -112,9 +119,10 @@\n score = 80\n strings:\n $x1 = /\$\{jndi:(ldap|ldaps|rmi|dns|iiop|http|nis|nds|corba):\/[\/]?[a-z-\.0-9]{3,120}:[0-9]{2,5}\/[a-zA-Z\.]{1,32}\}/\n+ $x2 = "Reference Class Name: foo"\n $fp1r = /(ldap|rmi|ldaps|dns):\/[\/]?(127\.0\.0\.1|192\.168\.|172\.[1-3][0-9]\.|10\.)/\n condition:\n- $x1 and not 1 of ($fp)\n+ 1 of ($x) and not 1 of ($fp)\n }\n \n rule SUSP_Base64_Encoded_Exploit_Indicators_Dec21 {\n@@ -123,6 +131,7 @@\n author = "Florian Roth"\n reference = "https://twitter.com/Reelix/status/1469327487243071493"\n date = "2021-12-10"\n+ modified = "2021-12-13"\n score = 70\n strings:\n /* curl -s /\n@@ -133,8 +142,11 @@\n $sb1 = "fHdnZXQgLXEgLU8tI"\n $sb2 = "x3Z2V0IC1xIC1PLS"\n $sb3 = "8d2dldCAtcSAtTy0g"\n+\n+ $fp1 = ") and 1 of ($sb)\n+ and not 1 of ($fp)\n }\n \n rule SUSP_JDNIExploit_Indicators_Dec21 {\n@@ -160,16 +172,32 @@\n score = 60\n strings:\n /* ${lower:X} - single character match /\n- $ = { 24 7B 6C 6F 77 65 72 3A ?? 7D }\n+ $x1 = { 24 7B 6C 6F 77 65 72 3A ?? 7D }\n / ${upper:X} - single character match /\n- $ = { 24 7B 75 70 70 65 72 3A ?? 7D }\n+ $x2 = { 24 7B 75 70 70 65 72 3A ?? 7D }\n / URL encoded lower - obfuscation in URL /\n- $ = "$%7blower:"\n- $ = "$%7bupper:"\n- $ = "%24%7bjndi:"\n- $ = "$%7Blower:"\n- $ = "$%7Bupper:"\n- $ = "%24%7Bjndi:"\n- condition:\n- 1 of them\n-}\n+ $x3 = "$%7blower:"\n+ $x4 = "$%7bupper:"\n+ $x5 = "%24%7bjndi:"\n+ $x6 = "$%7Blower:"\n+ $x7 = "$%7Bupper:"\n+ $x8 = "%24%7Bjndi:"\n+\n+ $fp1 = ") and not 1 of ($fp*)\n+}
rule SUSP_JDNIExploit_Error_Indicators_Dec21_1 {\n+ meta:\n+ description = "Detects error messages related to JDNI usage in log files that can indicate a Log4Shell / Log4j exploitation"\n+ author = "Florian Roth"\n+ reference = "https://twitter.com/marcioalm/status/1470361495405875200?s=20"\n+ date = "2021-12-10"\n+ modified = "2021-12-13"\n+ score = 70\n+ strings:\n+ $x1 = "FATAL log4j - Message: BadAttributeValueException: "\n+ condition:\n+ $x1\n+}\n'}}

It’s important to note that security teams must be logging data before it hits the application (and Log4j) for the Yara rules to work. 

Due to the broad network exploitation nature of vectors through which this vulnerability can be exploited and the fact that applying mitigations holistically across large environments will take time, we encourage defenders to look for signs of post-exploitation rather than fully relying on prevention. Observed post-exploitation activities such as coin mining, lateral movement, and Cobalt Strike are detected with behaviour-based detections.

One Comment

  • Thank you for the information. Please how can I run this on a windows server?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top