XZ Utils Backdoor
- Product
- Tukaani Project XZ Utils (liblzma)
- CVE
- CVE-2024-3094
- Disclosed
- 2024-03-29
- CVSS
- 10
- Auth
- pre-auth
- CISA KEV
- no
- Affected
- xz / liblzma 5.6.0 and 5.6.1 (mainly reached rolling and pre-release distros: Fedora 40/41 beta, Debian sid, openSUSE Tumbleweed, Kali, Arch tarballs).
- Fixed
- Downgrade to 5.4.6; clean upstream release 5.6.2.
Summary
A supply-chain backdoor planted over roughly two years by the maintainer persona 'Jia Tan' and found by Andres Freund after he noticed slow SSH logins. Through systemd's dependency on liblzma, the backdoor hooked OpenSSH's sshd so that the holder of a specific Ed448 key could run commands before authentication.
Root cause
Obfuscated test files (bad-3-corrupt_lzma2.xz, good-large_compressed.lzma) in the release tarball held a payload that the modified build-to-host.m4 macro injected into liblzma during the build. At runtime it used IFUNC resolvers and the rtld audit hooks to replace RSA_public_decrypt in sshd. Certificates carrying a payload signed with the attacker's Ed448 key were decrypted and run via system().
Impact
Pre-auth root RCE on affected sshd builds, limited to the attacker who holds the private key.
Public PoC
# xzbot patches the backdoor's Ed448 public key in a backdoored
# liblzma.so.5.6.1 with one you control (patch.py), then triggers it.
$ go install github.com/amlweems/xzbot@latest
$ xzbot -addr 127.0.0.1:2222 -cmd 'id > /tmp/.xz'
00000000 00 00 00 1c 73 73 68 2d 72 73 61 2d 63 65 72 74 |....ssh-rsa-cert|
...
2024/03/30 00:00:00 ssh: handshake failed: EOF
# /tmp/.xz on the target now contains uid=0(root)Source: amlweems - xzbot
Detection
xz --version / check liblzma version; run the detection script from the oss-security post or 'ldd $(which sshd) | grep liblzma' together with the version. Binarly and others released scanners for the backdoor's function hooks.
Mitigation
Downgrade to xz 5.4.6 or upgrade to 5.6.2+, rebuild affected images, and treat exposed systems as potentially compromised.