
The XZ Backdoor (CVE-2024–3094): How a Supply Chain Attack Nearly Compromised Every Linux Server
A breakdown of CVE-2024–3094, how the attacker hijacked liblzma, and why this almost became the biggest supply chain compromise in Linux history.
The 500 Milliseconds That Saved Linux
It didn't start with a malware alert.
It didn't start with a breach report.
It started with a half-second delay.
In March 2024, PostgreSQL developer Andres Freund noticed that SSH logins on his Debian system were taking slightly longer than usual — around 500ms more CPU time. That anomaly led to one of the most sophisticated open-source supply chain attacks ever discovered.
The culprit?
A backdoored version of XZ Utils.
Tracked as CVE-2024-3094, this attack nearly introduced remote code execution into millions of Linux systems — quietly, upstream, and signed by a trusted maintainer.
Let’s break down exactly what happened.
A trusted compression library quietly embedded into the SSH authentication path.
What Is XZ Utils — And Why This Was So Dangerous
XZ Utils is a widely used compression utility in Linux.
It provides the liblzma library.
That library isn’t obscure.
It’s everywhere.
It’s used indirectly by:
- systemd
- package managers
- archive tools
- OpenSSH (via libsystemd on many distributions)
So compromising XZ didn’t just mean compromising a compression tool.
It meant compromising the Linux ecosystem at a foundational layer.
How the Attacker Gained Control
This wasn’t a smash-and-grab attack.
It was patient.
Over roughly two years, a contributor using the name Jia Tan:
- Submitted small bug fixes
- Built credibility
- Gained commit access
- Eventually became release manager
According to reports, fake accounts were also used to pressure the original maintainer into adding more help — a subtle social engineering tactic.
This wasn’t opportunistic.
It was long-term trust infiltration.
The Critical Detail Most People Missed
The malicious code was not fully present in the public GitHub repository.
Instead, the attacker embedded critical pieces of the backdoor only in the release tarballs for:
- 5.6.0
- 5.6.1
That’s important.
Many systems build from official release tarballs, not directly from GitHub source trees.
This meant:
Git looked clean.
Releases were compromised.
The attack didn’t target SSH directly — it targeted trust in the release process.
That is advanced supply chain tradecraft.
The attack didn't target SSH directly - it targeted trust in the release process.
The Technical Breakdown (Semi-Deep)
Here’s where it gets interesting.
The backdoor consisted of multiple staged components:
Stage 1 — Build System Injection
A malicious build-to-host.m4 script was inserted into the tarball.
During the configure phase, it:
- Decoded data hidden inside test files
- Extracted obfuscated payloads
- Modified the build process
Specifically, it injected a malicious object:
liblzma_la-crc64-fast.o
This object was then compiled into liblzma.
Stage 2 — IFUNC Hooking
The malicious object replaced IFUNC resolvers:
crc32_resolve()crc64_resolve()
IFUNC (Indirect Functions) allow runtime selection of optimized implementations. The attacker abused this mechanism to execute malicious logic during dynamic linking.
This code:
- Installed an audit hook into the dynamic linker
- Waited for symbol resolution
- Intercepted the OpenSSH symbol:
RSA_public_decrypt
And then redirected it.
Stage 3 — OpenSSH Hooking
When SSH performed public key authentication, it eventually called:
RSA_public_decrypt()
The backdoor altered the function pointer in memory before RELRO protections locked it down.
The malicious function:
- Checked for a specially crafted certificate
- Verified attacker identity
- Executed
system()with attacker-controlled commands
That’s remote code execution.
Before authentication.
Not just an SSH bypass.
Full RCE.
How the XZ backdoor hijacked OpenSSH during dynamic symbol resolution.
Why It Was So Hard to Detect
The attacker implemented multiple stealth mechanisms:
- Only triggered on x86-64 Linux
- Required GNU ld
- Only activated during Debian/RPM builds
- Checked environment variables
- Detected debugging environments
- Avoided activation if
TERMorLD_DEBUGwere set
It even avoided triggering outside systemd contexts.
This wasn’t amateur malware.
This was operationally mature.
The Performance Clue That Exposed Everything
Because the backdoor parsed symbol tables in memory, it introduced latency.
That extra ~500ms during SSH startup was the anomaly.
Freund used:
perftracinggdb- Intel PT tracing
To isolate where execution diverged.
He discovered the malicious audit hook manipulating symbol resolution.
Without that curiosity?
This could have shipped to stable releases worldwide.
Affected Systems
Primarily:
- Debian sid
- Fedora rawhide
- Other pre-release distros
Stable LTS releases were mostly unaffected because they had not yet integrated 5.6.x.
That timing saved the ecosystem.
Detection and Mitigation
Immediate Action
CISA recommended downgrading to:
XZ 5.4.6
Detection Clues
- SSH daemon unusually slow
- liblzma 5.6.x present
- Unexpected symbol resolution behavior
Akamai and others published queries to detect loaded vulnerable libraries.
There was also an environment variable kill switch reportedly:
yolAbejyiejuvnup=Evjtgvsh5okmkAvj
Though downgrading remains the correct remediation.
Why This Supply Chain Attack Was Different
SolarWinds compromised a vendor.
XZ compromised upstream open source.
That’s deeper.
This wasn’t malware inserted after compilation.
It was injected into the build pipeline itself.
Git was clean.
Releases were poisoned.
That distinction changes how we think about trust in open source.
Lessons for Open Source and DevSecOps
This incident exposed several uncomfortable truths.
1. Trust Is Not a Security Control
Two years of clean commits built implicit trust.
Trust must be continuously verified.
2. Reproducible Builds Matter
If release tarballs had been reproducibly built and verified against Git, this would have been detected earlier.
Artifact verification is no longer optional.
3. Small Projects Can Create Global Blast Radius
XZ is a compression library.
Yet it nearly compromised SSH globally.
Dependency trees amplify risk.
4. Review the Build System — Not Just the Code
The malicious payload lived in:
- m4 build scripts
- test artifacts
- tarball-only files
Security review must include:
- CI pipelines
- build tooling
- release artifacts
Final Thought
The XZ backdoor wasn’t devastating because it failed.
It was devastating because it almost succeeded.
It was discovered by one engineer noticing half a second of delay.
That’s how thin the margin was.
The real question is:
How many similar operations haven’t been noticed yet?