Skip to content

CVE-2024-3094 — xz-utils backdoor

A maintainer with multi-year commit history shipped versions 5.6.0 and 5.6.1 of xz-utils containing a backdoor in liblzma. When the library was loaded into sshd (via systemd’s libsystemd linkage), the backdoor extracted a hidden RSA-shaped trigger from the SSH connection and granted the attacker code execution. The vulnerability was discovered because a microbenchmark unrelated to the backdoor showed a half-second slowdown on SSH connections.

This is one of the closest near-misses in supply-chain history. The backdoor shipped to a few rolling-release distros before discovery; most stable distros never picked it up.

Affected versions

  • xz-utils 5.6.0 and 5.6.1 — vulnerable.
  • xz-utils 5.4.6 / 5.4.x — clean.
  • xz-utils 5.6.2+ — clean (the backdoor was reverted).

The backdoor activates only when:

  • The build is run on a glibc-using x86_64 Linux system.
  • The build is invoked through autotools (the malicious code is in the m4/build-to-host.m4 macro from the release tarballs, not the git repo).
  • The resulting liblzma is linked into a process that also loads libsystemd or matches a small set of binary signatures (sshd is the named target).

This is the most thorough attack-narrow precondition list any single CVE has had. It still pays off if you’re running an affected distro.

Indicator-of-exposure

The system is exposed if:

  • The installed xz-utils (or the underlying liblzma) is 5.6.0 or 5.6.1.
  • The system is glibc x86_64 Linux.
  • The sshd binary on the system loads liblzma (typically through libsystemd).

Quick check:

# Version
xz --version

# Does sshd load liblzma transitively?
ldd "$(which sshd)" | grep lzma

If the version is in range and sshd links liblzma, treat the system as compromised — credentials, host keys, and anything in process memory at the time of any SSH connection are suspect.

Remediation strategy

The fix is all of:

  1. Roll back xz-utils to 5.4.x (or upgrade to 5.6.2+ on distros that ship it).
  2. Verify the installed binary is from the distro’s clean build. The malicious tarballs were signed; signature alone is not enough.
  3. Treat the host as compromised if it ran an affected sshd:
    • Rotate every credential the host had access to (cloud IAM keys, deploy tokens, signed certs).
    • Rotate SSH host keys.
    • Rotate any in-memory secrets (recently-decrypted credentials, mTLS private keys, token caches).
    • Audit auth logs for unexplained connections during the exposure window.
  4. Rebuild any artifact that was built on an affected host while it was affected. The backdoor allows arbitrary command execution; you cannot trust artifacts produced during the exposure window.

This is not a routine bump. The CVE narrative is a supply-chain compromise; the response is supply-chain incident response.

The prompt

You are remediating CVE-2024-3094 (xz-utils backdoor) on this
host or in this system image. Output exactly one of:

- A PR / change request rolling the package back, plus an
  incident-response checklist for the operator.
- A TRIAGE.md if the system is in the affected window and
  needs immediate human-led incident response.

This recipe is **not** a routine package bump. If exposure is
confirmed, do not auto-remediate; produce the incident
checklist and stop.

## Step 0 — Detect

1. Read the system's `xz-utils` / `liblzma` version (via the
   distro package manager, plus `xz --version` and
   `strings $(which xz) | grep -E '5\\.[456]'`).
2. Determine whether `sshd` on this system loads `liblzma`:
   `ldd $(which sshd) | grep lzma`.
3. Check the host's distro and version against published
   advisories (the affected window varies — Debian sid /
   Fedora 40 / Kali / openSUSE Tumbleweed all picked up the
   bad version at different times).

## Step 1 — Classify

- **Not affected:** Version is 5.4.x or ≥5.6.2; or `sshd`
  doesn't load `liblzma`. Document and stop.
- **Affected, never reachable from the network:** The host
  has affected `xz-utils` but `sshd` was firewalled-off /
  disabled / not running during the exposure window. Roll
  back the package; rotate any local secrets that were
  in-memory; document.
- **Affected, network-reachable sshd:** Treat as compromised.
  Stop here. Do not auto-remediate. Write a TRIAGE.md with
  the incident-response checklist and page the security
  on-call.

## Step 2 — Roll back the package (when classification is
"not network-reachable affected")

1. For Debian / Ubuntu rolling: `apt install xz-utils=5.4.5-*`
   (or the distro's clean-version pin). For Fedora 40:
   the distro shipped a rebuild — `dnf upgrade xz xz-libs`.
   For Arch / openSUSE Tumbleweed / Kali: follow the
   distro-specific roll-back advisory.
2. Verify the new package signature matches the distro's
   clean build.
3. Restart `sshd` (and any other process that loaded
   `liblzma`).

## Step 3 — Verify

1. `xz --version` prints a clean version.
2. `ldd $(which sshd) | grep lzma` shows the new path.
3. The host's `liblzma` SHA matches the distro's published
   clean SHA.

## Step 4 — Incident-response checklist (in the TRIAGE.md
when classification is "compromised")

The checklist must include:

- Rotate SSH host keys.
- Rotate every long-lived credential the host had access to:
  cloud IAM, registry tokens, deploy keys, mTLS private
  keys.
- Rotate any in-memory secrets that were decrypted during the
  exposure window.
- Pull the auth log and search for unexplained sessions.
- Identify and rebuild every artifact that was produced on
  this host during the exposure window.
- Report the incident through the org's IR channel.

The checklist is human-driven. The agent does not run any
of these steps.

## Stop conditions

- The system is in the "compromised" classification — write
  the checklist and stop.
- The distro's clean roll-back path is unclear and no
  upstream advisory exists for this distro. Triage.
- The host has multi-tenant exposure (shared host, multiple
  customers) — escalate before touching anything.

## Scope

- Do not roll back any package other than xz-utils / liblzma.
- Do not silently restart services without recording which.
- Do not modify SSH configuration other than as part of a
  documented IR action.
- Do not draft credential rotation actions; the IR checklist
  names them, the operator runs them.

Verification — what the reviewer looks for

  • The version verification ran and produced a clean number.
  • The ldd check confirmed sshd linked the new lib.
  • For compromised hosts: the IR checklist was followed (review the linked artefacts), not just the package rollback.
  • The reviewer does not trust the agent’s “not affected” classification without re-running the detection commands themselves.

Watch for

  • Distro-specific repackages. Some distros backported the fix into 5.6.x rather than rolling back. Don’t assume “5.6” is bad without checking the distro’s published clean SHA.
  • Container images built during the exposure window. A container image baked from an affected base inherits the backdoor. Rebuild every affected image; treat the affected image’s published copies as potentially compromised.
  • CI runners. A self-hosted CI runner with an affected xz-utils and a publicly-reachable sshd is exactly the shape this attack targeted. Audit those first.
  • liblzma is not always reached through sshd. Other binaries link liblzma for legitimate reasons; the backdoor’s preconditions narrow the impact, but other CVEs in the future may not.
  • Reproducibility from the git repo vs. tarball. The malicious code was in the release tarball but not in the git repository. Build provenance (“we built from git”) was the durable check; vendor signatures alone were not.

Related