CVE-2024-3094 in 60 seconds

XZ Utils is a compression project used throughout the Linux ecosystem. Its liblzma library can be loaded indirectly by processes that do not appear to use XZ themselves. In March 2024, XZ Utils 5.6.0 and 5.6.1 release tarballs were found to contain a deliberately constructed backdoor.

The attack did not simply add an obvious malicious source file. A trigger existed in the published release archive, while additional stages were concealed inside files that looked like compression test fixtures. Under a narrow set of Linux distribution build conditions, those pieces modified the resulting liblzma library.

On some distributions, OpenSSH’s sshd process loaded libsystemd for systemd notification, and libsystemd in turn loaded liblzma. That transitive dependency carried the modified library into the privileged SSH server before authentication. Public analysis showed the implant interfering with the RSA verification path. Its intended result was unauthorized remote access — effectively a pre-authentication backdoor for an attacker holding the corresponding secret key material.

The shortest accurate summary is:

malicious XZ release tarball
  -> distribution package build activates hidden stages
  -> modified liblzma is installed
  -> selected sshd builds load liblzma through libsystemd
  -> SSH authentication path is intercepted
  -> attacker can seek unauthorized remote access

This was therefore both a software supply-chain compromise and an OpenSSH authentication attack path. It was assigned CVE-2024-3094.

What are XZ, liblzma, and sshd?

xz is a common command-line compression format and tool. liblzma is the reusable software library behind much of that functionality. Package managers and operating-system components can depend on the library even when administrators never invoke the xz command themselves.

sshd is the server process that accepts incoming SSH connections. OpenSSH did not directly depend on XZ. The surprising connection existed on distributions that patched OpenSSH to notify systemd when the service was ready:

sshd -> libsystemd -> liblzma

That indirect edge is essential to understanding the incident. The attackers did not need XZ to be an SSH component. They needed their modified library to be loaded into the SSH server process, where it could influence authentication before a user logged in.

What happened?

The public incident record supports the following sequence:

  1. A contributor using the identity Jia Tan held release responsibility in the XZ project.
  2. Binary-looking files were added to the repository as compression test fixtures. On their own, they did not activate the full backdoor.
  3. XZ Utils 5.6.0 and 5.6.1 release tarballs were created and signed by Jia Tan. These downloadable archives included activation logic that was absent from an ordinary build of the corresponding Git source.
  4. When a targeted x86-64 Linux package was built with the expected GNU toolchain and Debian or RPM packaging signals, the release-only logic extracted hidden stages from the test files.
  5. Those stages changed the liblzma build. On a compatible runtime dependency path, the modified library entered sshd and redirected part of its RSA verification behavior.
  6. PostgreSQL developer Andres Freund noticed that SSH logins on Debian unstable consumed unusual CPU time and produced Valgrind errors. His investigation traced the anomaly to the backdoored XZ release and was published on 29 March 2024.
  7. Distributions removed or downgraded the affected packages, the compromised releases were withdrawn, and XZ Utils 5.6.2 was published as a cleanup release.

This chronology is why describing the incident merely as an “XZ vulnerability” is misleading. It was not an accidental coding mistake found in normal compression logic. It was a patient, selective attempt to make trusted release infrastructure produce a malicious library.

Who was actually affected?

The presence of an xz package alone did not prove exposure. The known attack required a chain of conditions:

  • a package derived from the malicious 5.6.0 or 5.6.1 release tarball;
  • the targeted x86-64 Linux and GNU build environment;
  • compatible glibc and linker behavior;
  • distribution packaging conditions that activated the hidden stages;
  • an sshd runtime path that loaded the resulting liblzma, commonly through libsystemd.

The releases were caught before broad adoption by stable Linux distributions. Debian unstable, Fedora Rawhide, Fedora 40 beta, and some openSUSE testing packages were central to the initial response, but package presence and working exploit reachability were not identical. Red Hat stated that RHEL was unaffected and that Fedora 40 beta contained affected XZ packages while the actual malware exploit did not appear to activate in those builds.

For an operator, the correct question is not only “Is the version 5.6.x?” It is “Which exact artifact was packaged, how was it built, and can the installed library reach the exposed SSH process?”

What I verified

This article now separates the public incident from my own validation boundary:

  • The maintainer’s incident record confirms that the 5.6.0 and 5.6.1 release tarballs contained the backdoor and were created and signed by Jia Tan.
  • The cleanup commit says it removes the backdoor and deletes suspicious fixtures including bad-3-corrupt_lzma2.xz and good-large_compressed.lzma.
  • The initial disclosure documents release-only activation logic, selective build conditions, the dependency path into sshd, and observed interception of RSA verification.
  • I compared the clean-release notes, repository cleanup, initial disclosure, and distribution response instead of relying on a single narrative source.
  • This remains a static artifact and patch reproduction. I did not unpack or execute malicious stages, trigger the implant, or claim host-level exploitation evidence.

Deep dive: the release artifact was a separate security boundary

The initial oss-security report identified a crucial asymmetry. Part of the activation logic was present in the 5.6.0 and 5.6.1 release tarballs but absent from the corresponding Git source. The tarballs included a modified m4/build-to-host.m4; generated archives from the Git hosting service did not contain the same injected line.

That release-only macro extracted additional stages from files that looked like compression test inputs. Under selected build conditions, the stages altered the generated liblzma build. The result was not simply “malicious source compiles into malicious software.” It was a multi-object construction in which no single benign-looking object explained the final binary.

ARTIFACT DIVERGENCE Repository tagreviewed source Git buildimplant absent Release tarballextra macro Test fixtureshidden stages liblzmamodified build sshd pathpre-auth reach Same version label, different security result
The decisive comparison is not only vulnerable commit versus fixed commit. It is signed release artifact versus the source tree users believed it represented.

This is why “we built the tag and saw nothing” was a weak negative control. It exercised a different input. For projects that publish generated files, the release archive is executable supply-chain state and requires its own provenance, reproducibility, and review.

Selection logic reduced noise and delayed discovery

The activation stage checked several environmental properties. Public analysis documented an x86-64 Linux GNU build, GCC and GNU ld, and Debian or RPM packaging signals among the conditions. The backdoor therefore avoided many developer workstations, alternative toolchains, direct Git builds, and unsupported targets.

Selectivity served two purposes. First, it concentrated the payload where distribution packages would place it in realistic dependency graphs. Second, it made failed reproduction look like evidence of safety. An investigator changing the compiler, build entry point, architecture, or packaging directory could silently take a clean branch.

The observation is reusable: anti-analysis does not require detecting a debugger. A malicious build can simply demand a narrow set of normal production properties. Each property is reasonable alone; their conjunction separates release infrastructure from casual inspection.

The dependency edge into sshd was distribution-specific

OpenSSH did not directly depend on liblzma. The public report explains that some Linux distributions patched OpenSSH for systemd notification. That integration pulled libsystemd into the server, and libsystemd depended on liblzma. The implant exploited this transitive route.

This corrects two misleading inventories. A list of direct OpenSSH dependencies would miss the edge. A fleet search for any XZ 5.6 package would overstate reachability because the malicious archive, build conditions, architecture, libc, and linkage all mattered.

REACHABILITY, NOT VERSION PANIC 5.6.x packagewhich artifact? Build contextconditions match? Runtime graphlibrary reachable? Exposureall must hold sshdpatched build libsystemdtransitive edge liblzmamodified object
A package name is an inventory clue, not a complete finding. Artifact identity and the final runtime dependency graph decide whether the malicious code can reach the exposed process.

What the clean release changes

XZ Utils 5.6.2 explicitly removed the backdoor. The response also removed compromised test files, reviewed release machinery, and restored project control. For operators, upgrading is necessary, but replacement alone is not the full incident response. Systems that installed a malicious build should be treated as having executed untrusted upstream code during packaging or runtime.

The important fixed property is artifact equivalence with reviewed source. A clean version number helps only when the package came from a trusted channel and the distributor confirms its provenance. Rebuilding a known-good source, verifying package signatures, and comparing distributor advisories provide stronger evidence than searching for one file name left by the implant.

Evidence matrix

QuestionWhat I checkedConfidenceLimit
Which releases contained the backdoor?I matched the project response and initial disclosure on the 5.6.0 and 5.6.1 tarballs.HighRepacked downstream artifacts require distributor-specific verification.
Why could a Git build look clean?I verified the reported divergence between release-only macro logic and repository source.HighMirrors and cached archives may preserve different combinations.
How did code reach sshd?I reconstructed the distribution-specific path from sshd through libsystemd to liblzma.HighThe exact dependency graph differs by platform and build flags.
Was every XZ 5.6 installation exploitable?I found no support for that blanket claim; artifact, build, target, and linkage were selective.HighPublic records cannot enumerate every custom build.
What release removes the known implant?I checked the 5.6.2 cleanup release and its backdoor-removal commit.HighA clean package does not by itself prove that an earlier compromise had no impact.
Does this analysis prove a host was accessed?No. It establishes technical reachability from published evidence.HighHost-specific impact requires logs, package provenance and forensic evidence.

Safe validation without loading the implant

Begin with package provenance, not a network probe. Record the installed package version, package hash, repository channel, signing identity, installation time, and the distribution advisory. A version string is insufficient because some distributions never shipped the compromised releases, while development channels and manually imported tarballs may have done so briefly.

Next, reconstruct the build input. Compare the exact source archive against the distributor’s known-good manifest and inspect whether it contains the release-only macro and compromised fixture history described by the maintainers. Perform this work on inert copies. Do not run configure, decompress the embedded stages into a shell, or load the resulting library.

Then inspect the final binary relationship using static package metadata and dependency tools. The question is whether the deployed server process could load the affected liblzma, directly or transitively. This is safer and more precise than repeatedly connecting to SSH and interpreting timing variance as proof.

Useful negative controls are:

  • an archive generated directly from the clean Git tag rather than the malicious release tarball;
  • XZ 5.6.2 from the same trusted distributor;
  • a target whose server binary has no runtime path to liblzma;
  • a package hash the distributor explicitly lists as unaffected;
  • the same static inspection performed without executing any archive-provided build script.

Timing anomalies helped discover the incident, but they are not a reliable fleet verdict. CPU load and login latency have many causes, while the implant deliberately varied its behavior under analysis. Preserve timing as supporting telemetry, not the sole exposure decision.

My conclusion

Replace affected packages with a trusted 5.6.2-or-later build or the distribution’s documented clean package. If a compromised artifact was installed, rotate relevant credentials and perform incident response according to the process’s exposure and available evidence; absence of a known trigger in logs is not proof that the system remained untouched.

My conclusion is that repository review alone could not answer what downstream users actually installed. The release tarball, generated build logic, distributor environment, and final library relationship all had to be checked as one chain. Source review ends too early when users execute a different artifact.

Public sources

Sources & limits

Evidence used for this analysis

Sources checkedAugust 24, 2026

Version and exploitation status can change; follow the linked vendor records.

Review statusAuthor review complete

The author completed a technical review. This does not, by itself, claim lab reproduction.

◈ Cite This ResearchBibTeX · Markdown

Reference this analysis, root-cause teardown, or vulnerability discovery in your technical reports or academic publications:

@misc{jankesec_xz_utils_release_artifact_cve_2024_3094_2025,
  author       = {Sevban D\"{o}nmez},
  title        = {CVE-2024-3094: How a Backdoored XZ Release Reached OpenSSH},
  year         = {2025},
  howpublished = {\url{https://jankesec.com/research/xz-utils-release-artifact-cve-2024-3094/}},
  note         = {jankesec technical security research (CVE-2024-3094)}
}