CVE-2024-3094 (xz/liblzma backdoor) — what homelabs had to fear and how to check
In March 2024 a Microsoft engineer noticed sshd on his Debian testing box was unusually slow during login. Two days later he had unwound a multi-stage backdoor planted across two years of patient social engineering by a contributor to xz-utils. The affected versions (xz 5.6.0 and 5.6.1) had landed in bleeding-edge distros — Fedora Rawhide, Debian sid, openSUSE Tumbleweed, Kali rolling. Stable LTS releases dodged the bullet by hours. This post explains what CVE-2024-3094 actually did, who was exposed, the single command you can still run today to check, and what supply-chain hygiene a homelab can realistically practice.
The TL;DR
- What it is: a backdoor injected into the
build system of
xz-utils(the library every Linux distro uses for.tar.xzcompression). The backdoor added itself toliblzma.so, whichsshdloads transitively via systemd'slibsystemd. Once loaded, the backdoor hookedRSA_public_decryptinsidesshdand acted as a covert command channel: an attacker whose payload was signed with the backdoor's hard-coded Ed448 public key could submit arbitrary commands through sshd's pre-authentication path, which the hook then executed as root. The Ed448 key is the attacker's authentication gate to the backdoor itself, not a bypass of sshd's normal RSA authentication for legitimate users. - Affected versions:
xz-utils5.6.0 and 5.6.1, released February–March 2024. Earlier versions (5.4.x and below) and 5.6.2+ are clean. - Who shipped it: Fedora Rawhide and 41-prerelease,
Debian unstable/testing (sid/trixie), openSUSE Tumbleweed, Kali
rolling, Arch (briefly, before
liblzma's build config differed enough that the backdoor wouldn't trigger). Not shipped: Ubuntu 22.04 / 24.04, Debian stable (bookworm), Rocky / AlmaLinux 8/9, RHEL, any container base image built before March 2024. - How it was caught: Andres Freund, a
PostgreSQL maintainer at Microsoft, noticed sshd was eating
~500 ms of CPU per failed login on a Debian sid box. He tracked
the slowdown to
liblzma, found the backdoor's symbol-resolution machinery, and disclosed publicly on 2024-03-29 — three weeks after 5.6.1 entered testing repositories. Stable distros pulled the affected versions within hours. - What every homelab should do today: run the one-line check below. If you're on Ubuntu LTS or Debian stable you're almost certainly clean. If you've got a rolling-release box (Arch, Tumbleweed, Fedora) or a container built off a Rawhide base in March 2024, verify before assuming.
The one-line check
Run this on every Linux box in your homelab:
strings $(ldconfig -p | grep -m1 liblzma.so.5 | awk '{print $NF}') 2>/dev/null \
| grep -E "^5\\.(6\\.0|6\\.1)$" || echo "clean (not 5.6.0/5.6.1)"
The check works like this: ldconfig -p finds the
installed liblzma.so.5, strings dumps
its embedded version banner, and grep matches only
the affected versions. Most boxes will print clean (not
5.6.0/5.6.1) and you can move on. If you see
5.6.0 or 5.6.1, your distro shipped the
backdoored version and you need to upgrade
xz-utils immediately and rotate any SSH keys that
authenticated to that box during the affected window.
How the backdoor actually worked
The technical mechanism is worth understanding because it
reframes "supply-chain attack" from an abstract risk into
something concrete. The backdoor was a multi-stage payload
hidden in test fixture files (tests/files/bad-3-corrupt_lzma2.xz
and tests/files/good-large_compressed.lzma) that
looked like deliberately-malformed compression test cases. The
build script's m4/build-to-host.m4 macro extracted
payload bytes from these files only when:
- The build was on x86-64 Linux,
- The
$RPM_ARCHor$DEB_BUILD_ARCHenvironment variable was set (so it triggered only inside distro packaging, not on a developer's local./configure), - And the build was producing a shared library, not a static.
Once linked into liblzma.so, the backdoor used
glibc's IFUNC resolver mechanism to hook
RSA_public_decrypt at first call. Because
sshd on systemd-using distros transitively loads
libsystemd → liblzma, every sshd
child process inherited the hook. When an attacker presented a
pubkey signed with their specific Ed448 key as part of the SSH
handshake, the hook decoded a command from the certificate and
executed it via system(3) — pre-auth, as root.
Three things made this dangerous beyond the obvious:
- Two-year social-engineering buildup. The
attacker (using the persona "Jia Tan" /
JiaT75) had been a productive xz-utils contributor since 2022, gradually gaining maintainer status. Sustained pressure from sock-puppet accounts pushed the original maintainer to share commit access. The malicious commits arrived months later, after trust was established. - The payload was distro-aware. It only
triggered inside RPM/DEB build environments, so an upstream
diff review of
./configure && makelooked clean. You had to build a package the way Fedora or Debian builds packages to see the backdoor at all. - The Ed448 key was held only by the attacker. The backdoor verified the signing key on every connection. So even after the existence of the backdoor became public, nobody else could exploit it — only the original implanter had the key. This kept the active exploitation window very small.
Why your stable LTS box is almost certainly clean
Distros split into two release models, and one of them effectively immunised against this attack:
Stable / LTS distros (Ubuntu 22.04, Debian stable, RHEL, Rocky, AlmaLinux) lock to a frozen package set at release time. Updates within the LTS lifetime are limited to security patches and explicit point-release backports. xz 5.6.0 simply never entered Ubuntu 22.04's archive — Ubuntu was on 5.2.5 at the time and stayed there. Same story across Debian-stable and the RHEL family.
Rolling-release distros (Arch, Tumbleweed,
Gentoo, Kali, Debian sid) ship upstream updates within days. xz
5.6.0 and 5.6.1 landed in those archives and remained there
until the disclosure, giving an exposure window of roughly three
weeks. Whether your specific box was actually backdoored depends
on when in that window you ran pacman -Syu /
zypper dup / apt update && apt upgrade.
Container base images are the trickier case. If
you pulled fedora:rawhide, debian:sid, or
archlinux:latest in March 2024 and froze a derived
image, that image still contains the backdoor today — even
though the upstream archives have long since rolled forward.
Audit container base-image dates before assuming clean.
What this means for homelab supply-chain hygiene
Three lessons that generalise beyond this specific incident:
1. Stable LTS is a security feature, not just a stability feature. The "boring" choice of running Ubuntu 22.04 instead of Arch on your homelab boxes is also the choice that adds a multi-week buffer between an upstream compromise and your machine. Reflexively chasing the latest kernel and library versions has costs that aren't visible until events like this make them visible.
2. SBOMs without scanning are theatre. Every
Linux box "has an SBOM" — dpkg -l or rpm -qa
enumerate every installed package and version. The gap is
between having that list and continuously matching it against
published CVE data. A homelab with five boxes has roughly 1,000
packages installed across them; manually checking each against
NVD weekly is not realistic. This is exactly the gap
Noxen is built to close — agentless SSH
inventory plus automatic CVE matching against a daily-refreshed
feed, with distro-aware version comparison so backports get
credited correctly. See
how the
agentless inventory works for the mechanism.
3. Build provenance is the next horizon. CVE- 2024-3094 wouldn't have been caught by reproducible builds (the malicious payload was in the source, just obfuscated as test fixtures), but it would have been caught by stricter review practices for downstream packagers. Distros are tightening their provenance pipelines as a result — Debian's reproducible builds project has gained urgency. Homelabbers can contribute by running on reproducibly-built distros where possible and being suspicious of "convenience" repositories that haven't earned trust.
How Noxen would have flagged it
Once xz 5.6.0 and 5.6.1 had a CVE assigned (initially only "CVE-2024-3094") with affected-version metadata in NVD and OSV, Noxen's matcher would have surfaced any box running an affected version on the next scan. The flow:
- Agentless SSH probe runs
dpkg -l xz-utils(orrpm -q xzon RPM distros), captures version. - Matcher consults the
daily-refreshed CVE feed, finds
CVE-2024-3094 with
affected: xz-utils < 5.6.2. - Distro-aware version comparison (Debian dpkg ordering for Ubuntu/Debian, RPM ordering for Fedora/Rocky) confirms the installed version satisfies the vulnerable range.
- Finding lands in the report with severity Critical, with the recommended fix being "upgrade xz-utils to ≥ 5.6.2 and rotate SSH keys that authenticated to this host during the affected window."
The "rotate keys" recommendation isn't from CVE metadata — that's the kind of operational context Noxen layers on top of the raw NVD/OSV data via remediation guidance. CVE feeds tell you what's broken; remediation tells you what to do about it.
The homelab playbook for the next CVE-2024-3094
A general pattern, condensed from the xz incident and similar supply-chain events:
- Inventory weekly. You can't respond to a supply-chain CVE in 24 hours if you don't already know what you're running. Weekly automated SSH inventory across every homelab box gives you the package-list-as-asset-register that emergency response requires.
- Subscribe to the right firehoses. The oss-security mailing list and the NVD CVE feed are the two sources every homelab security blog post recommends, but actually reading them for signal vs. noise is hard. EPSS plus KEV (covered in the EPSS post) does most of the prioritisation for you.
- Practice rotation drills. The xz response recommendation included rotating SSH keys that touched affected boxes. If you haven't rotated SSH keys in your homelab in the last year, you'd discover during an actual incident that you can't tell which keys touched which boxes. See SSH key hygiene for a manageable rotation cadence.
- Don't run rolling-release as a Linux beginner.
This is contrarian advice, but: if you're not committed to
reading every
pacman -Syuoutput and tracking CVE feeds for fresh-from-upstream packages, stable LTS is the right default for a homelab box. Save rolling for desktops where you can hold off updates for a week without breaking a service.
Further reading
- Andres Freund's original disclosure email — the timeline of how the slow login became a backdoor unwind.
- Russ Cox's deep-dive on the build-script payload — the most readable technical breakdown.
- Binarly's reverse-engineering of the binary payload — what the IFUNC hook actually did at runtime.
- Internal: how Noxen's agentless inventory works, continuous CVE scanning vs patching, browse the live Noxen CVE feed.
Want this kind of monitoring across your fleet? Noxen scans every Linux/BSD/macOS host you own over SSH (no agents) and matches installed package versions against a daily-refreshed CVE feed. Pricing & download.
Scan your Linux fleet from your Mac
Noxen runs nightly agentless audits over SSH and shows only what changed since the last scan — new CVEs, config drift, newly exposed admin services. Mac-native control plane, no SaaS round-trip.