Log4Shell
CVE-2021-44228 — unauthenticated remote code execution via JNDI lookup injection
Summary
Log4Shell (CVE-2021-44228) is a critical remote code execution vulnerability in the Apache Log4j Java logging library. It allows attackers to execute arbitrary code by injecting malicious payloads into log messages via JNDI lookups. The vulnerability affects Log4j versions 2.0-beta9 through 2.14.1 and has a CVSS score of 10.0.
Key facts:
- Discovered in November 2021.
- Widely exploited in the wild shortly after disclosure.
- Affects numerous Java-based applications and services globally.
Background
The vulnerability was discovered by Chen Zhaojun of Alibaba Cloud's security team and privately reported to the Apache Software Foundation on November 24, 2021. A proof-of-concept exploit was published on GitHub on December 9, 2021, leading to widespread awareness and exploitation. Apache released the initial patch (version 2.15.0) on December 10, 2021, followed by additional fixes in 2.16.0 and 2.17.0 to address related issues.
Notification: The issue was assigned CVE-2021-44228 on November 26, 2021. Public disclosure occurred on December 9, 2021.
Vendor Patch Timeline: Apache promptly released patches, with 2.15.0 disabling message lookups, 2.16.0 removing support for them, and further enhancements in subsequent versions.
Impact
- Exploitation Potential: Allows unauthenticated remote code execution (RCE) by controlling log messages, such as user inputs in web applications.
- Scope: Affects millions of Java applications, including servers, cloud services, and consumer software like Minecraft.
- Potential Consequences: Data theft, ransomware deployment, server takeover, and supply chain attacks.
- Widespread Adoption: Log4j is embedded in many third-party libraries and frameworks, amplifying the impact.
What's Log4j
Apache Log4j is a popular open-source Java logging framework developed by the Apache Software Foundation. It provides developers with a flexible way to log application events, errors, and debug information. Log4j is widely used in enterprise applications, web services, and other Java-based systems due to its performance and configurability.
Implications
Log4Shell matters because of Log4j's ubiquity in the software ecosystem, making it a prime target for attackers. Operationally, it poses risks of system compromise, data breaches, and downtime. Security risks include easy exploitation without authentication, potential for wormable attacks, and challenges in identifying affected systems due to embedded dependencies.
Mitigation
Immediate (0–7 days)
- Upgrade Log4j to version 2.17.0 or later.
- Set the system property
log4j2.formatMsgNoLookupsto true for temporary mitigation. - Block outbound LDAP and RMI traffic at the network level.
Short-Term (1–4 weeks)
- Scan all systems and applications for vulnerable Log4j instances using vulnerability scanners.
- Apply patches to all affected software and monitor for exploitation attempts.
- Implement web application firewalls (WAF) rules to block malicious payloads.
Medium-Term (1–3 months)
- Conduct thorough audits of Java dependencies in all projects.
- Enhance logging and monitoring to detect anomalous behavior.
- Train development teams on secure logging practices.
Long-Term (3–6+ months)
- Migrate to alternative logging frameworks if feasible.
- Integrate automated dependency scanning into CI/CD pipelines.
- Develop incident response plans for similar supply chain vulnerabilities.
Timeline
| Date | Event |
|---|---|
| November 24, 2021 | Vulnerability reported to Apache by Alibaba Cloud security team. |
| November 26, 2021 | CVE-2021-44228 assigned. |
| December 1, 2021 | Earliest evidence of exploitation in the wild. |
| December 9, 2021 | Proof-of-concept exploit published on GitHub; public disclosure. |
| December 10, 2021 | Apache releases Log4j 2.15.0 patch. |
| December 13, 2021 | Apache releases 2.16.0, removing message lookups. |
| December 17, 2021 | CISA issues emergency directive for federal agencies. |
| December 28, 2021 | Apache releases 2.17.0 addressing additional issues. |
Key Takeaways
- Prioritize patching critical vulnerabilities in widely used libraries like Log4j.
- Implement comprehensive vulnerability scanning and dependency management.
- Monitor for exploitation and prepare rapid response plans.
- Highlight the risks of open-source supply chain attacks to leadership.
- Enhance network controls to limit outbound connections from servers.
References
- NVD — CVE-2021-44228 Detail (Vendor Advisory)
- Apache Log4j Security Vulnerabilities (Vendor Advisory)
- Log4Shell — Wikipedia (Research Report)
- Apache Log4j Vulnerability CVE-2021-44228: Analysis and Mitigations — Palo Alto Networks (Research Report)
- Apache Log4j Vulnerability Guidance — CISA (Research Report)
- The Apache Log4j vulnerabilities: A timeline — CSO Online (Media Coverage)
- Inside the Log4j2 vulnerability (CVE-2021-44228) — Cloudflare (Media Coverage)
Identification Tool
Checklist for end users and technicians to confirm if a system is affected:
- Determine if the system runs Java applications or services.
- Search for files named log4j-core*.jar in application directories, libraries, or system paths.
- Extract the JAR file and check META-INF/maven/org.apache.logging.log4j/log4j-core/pom.properties for the version.
- If the version is between 2.0-beta9 and 2.14.1, the system is vulnerable.
- Check for the presence of JndiLookup.class in the JAR (indicates potential vulnerability if not patched).
- Use vulnerability scanners like those from Qualys or Tenable to scan the system.
- Review application dependencies and vendor advisories for embedded Log4j usage.
PowerShell Check Script
Add-Type -AssemblyName System.IO.Compression.FileSystem
function Get-Log4jVersion {
param ($jarPath)
try {
$zip = [IO.Compression.ZipFile]::OpenRead($jarPath)
$pomEntry = $zip.Entries | Where-Object { $_.FullName -eq 'META-INF/maven/org.apache.logging.log4j/log4j-core/pom.properties' }
if ($pomEntry) {
$stream = $pomEntry.Open()
$reader = New-Object IO.StreamReader($stream)
$text = $reader.ReadToEnd()
$reader.Close()
$stream.Close()
$versionLine = $text -split "`n" | Where-Object { $_ -match '^version=' }
if ($versionLine) {
return $versionLine -replace 'version=', ''
}
}
$zip.Dispose()
} catch {}
return "Unknown"
}
$vulnerableJars = @()
$drives = Get-PSDrive -PSProvider FileSystem
foreach ($drive in $drives.Root) {
Get-ChildItem -Path $drive -Recurse -Filter "log4j-core*.jar" -ErrorAction SilentlyContinue | ForEach-Object {
$version = Get-Log4jVersion $_.FullName
if ($version -ne "Unknown") {
$ver = [version]$version
if ($ver -ge [version]"2.0" -and $ver -lt [version]"2.17.0") {
$vulnerableJars += "$($_.FullName) - Version: $version"
}
}
}
}
if ($vulnerableJars.Count -gt 0) {
Write-Host "Vulnerable Log4j found:" -ForegroundColor Red
$vulnerableJars | ForEach-Object { Write-Host $_ -ForegroundColor Red }
Write-Host "Update needed" -ForegroundColor Red
} else {
Write-Host "No vulnerable Log4j found or versions are safe." -ForegroundColor Green
Write-Host "OK" -ForegroundColor Green
}