Archived material. This page is preserved for historical and educational value. It reflects the threat landscape, available guidance, and research context at the time it was written or last updated. It should not be treated as a current security advisory or production remediation guidance. See the Threat Archive index for context and full listing.
Vulnerability · Apache Log4j · 2021

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:

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

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)

Short-Term (1–4 weeks)

Medium-Term (1–3 months)

Long-Term (3–6+ months)

Timeline

DateEvent
November 24, 2021Vulnerability reported to Apache by Alibaba Cloud security team.
November 26, 2021CVE-2021-44228 assigned.
December 1, 2021Earliest evidence of exploitation in the wild.
December 9, 2021Proof-of-concept exploit published on GitHub; public disclosure.
December 10, 2021Apache releases Log4j 2.15.0 patch.
December 13, 2021Apache releases 2.16.0, removing message lookups.
December 17, 2021CISA issues emergency directive for federal agencies.
December 28, 2021Apache releases 2.17.0 addressing additional issues.

Key Takeaways

References

Identification Tool

Checklist for end users and technicians to confirm if a system is affected:

  1. Determine if the system runs Java applications or services.
  2. Search for files named log4j-core*.jar in application directories, libraries, or system paths.
  3. Extract the JAR file and check META-INF/maven/org.apache.logging.log4j/log4j-core/pom.properties for the version.
  4. If the version is between 2.0-beta9 and 2.14.1, the system is vulnerable.
  5. Check for the presence of JndiLookup.class in the JAR (indicates potential vulnerability if not patched).
  6. Use vulnerability scanners like those from Qualys or Tenable to scan the system.
  7. 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
}