Executive Summary

On March 29, 2024, a critical security vulnerability affecting the xz/liblzma data compression library was publicly disclosed. The vulnerability, assigned CVE-2024-3094, was the result of a supply chain attack where a malicious actor compromised the upstream source code repository of the xz project and introduced a backdoor. This backdoor, when activated during the build process, would enable remote code execution on affected systems, particularly targeting the OpenSSH server.

The initial discovery was made by Andres Freund, a PostgreSQL contributor, who noticed unusual behavior in the OpenSSH server after a package update involving the compromised xz library. Freund’s investigation revealed that the source code and release tarballs of xz versions 5.6.0 and 5.6.1 had been tampered with, allowing the execution of obfuscated scripts during the build process. These scripts would ultimately inject a binary payload into the compiled liblzma library, enabling the backdoor.

Immediate action is recommended for all users and developers who may have installed or distributed the affected xz versions. The Cybersecurity and Infrastructure Security Agency (CISA) advises downgrading to an uncompromised version, such as XZ Utils 5.4.6 Stable, and thoroughly scanning systems for any potential malicious activity. It is crucial to report any positive findings to CISA for further analysis and response.

Background Story

The malicious actor behind this supply chain attack is believed to be an individual known as Jian Tang, who operated under the GitHub username JiaT75. Tang’s involvement with the xz project started in 2022, when he submitted a patch through a mailing list. Initially, Tang’s contributions were innocuous, but soon after, a new persona named Jigar Kumar emerged, pressuring the xz maintainer, Lasse Collin, to add another maintainer to the project.

Three days after the initial pressure from Jigar Kumar, JiaT75 made their first commit to the xz repository, titled “Tests: Created tests for hardware functions.” From that point on, JiaT75 became a regular contributor to the project and gradually gained trust within the community.

In March 2023, the primary contact email for the xz project in Google’s oss-fuzz was updated to JiaT75’s email address, indicating a significant increase in their influence over the project. Around the same time, JiaT75 introduced testing infrastructure that would later be used in the exploit chain.

As JiaT75’s contributions continued, their tactics became more sophisticated. In July 2023, they opened a pull request in oss-fuzz to disable a specific feature for fuzzing builds, potentially masking the malicious changes they were planning to introduce. Additionally, JiaT75 opened an issue about a warning in the clang compiler, drawing attention to a specific code construct that would later be exploited.

In 2024, JiaT75 made the final steps necessary for the backdoor’s execution. They committed obfuscated test files containing the exploit code and modified the build process to include a malicious script that would extract and inject the binary payload during compilation.

The complexity of JiaT75’s tactics, including the use of multiple personas and the gradual increase in their influence over the project, suggests a well-planned and executed supply chain attack. Their ability to gain trust within the community and introduce changes over an extended period made the eventual compromise of the xz project more difficult to detect.

Technical Details

The backdoor introduced by the malicious actor, Jian Tang (JiaT75), was a multi-stage attack that targeted the build process of the xz/liblzma library. The attack was designed to be activated only under specific conditions, including targeting x86-64 Linux systems, using the GNU Compiler Collection (GCC) and the GNU linker (ld), and being part of a Debian or RPM package build process.

The initial stage of the attack involved modifying the m4/build-to-host.m4 file in the xz source code repository. This file contained a sed command that would extract an obfuscated script from the tests/files/bad-3-corrupt_lzma2.xz file during the build process. The extracted script was then executed, initiating the next stage of the attack.

The extracted script performed various checks to ensure the target environment met the required conditions. If the conditions were met, the script would modify the src/liblzma/Makefile file, introducing a command that would be executed at the end of the configure step. This command involved extracting and decoding data from the tests/files/good-large_compressed.lzma file using a series of obfuscated steps.

One of the key obfuscation techniques employed was the use of the awk command to implement an RC4-like decryption algorithm. The obfuscated data from the good-large_compressed.lzma file was processed through this decryption algorithm, revealing a binary payload that would ultimately be injected into the compiled liblzma library.

The binary payload was extracted from the decrypted data and saved as the file liblzma_la-crc64-fast.o. This file contained the core of the backdoor functionality, which would be executed when the compromised liblzma library was used by other applications, such as the OpenSSH server.

The key vector for the backdoor’s activation was the OpenSSH server’s reliance on the systemd library, which in turn depended on the compromised liblzma library. When the OpenSSH server was started, the backdoor would intercept the execution flow by replacing the ifunc resolvers crc32_resolve() and crc64_resolve() with malicious code.

The backdoor code would then perform additional checks, such as verifying the program arguments and environment variables. If the conditions were met, the backdoor would install an audit hook into the dynamic linker, allowing it to modify the Global Offset Table (GOT) entries for specific functions, such as RSA_public_decrypt.

By hijacking the RSA_public_decrypt function, the backdoor enabled remote code execution on the compromised system. The attacker could send a specially crafted public key containing a payload, which would be extracted, decrypted, and executed by the backdoor code.

According to security researcher Filippo Valsorda, the backdoor verified a signature on the server’s host key using a fixed Ed448 key and then passed the payload to the system() function, effectively allowing remote code execution. Valsorda also noted that the backdoor could be triggered using OpenSSH certificates, which include the signer’s public key and are automatically verified by OpenSSH during parsing.

While the backdoor was designed to revert to regular operation if the payload was malformed or the signature did not verify, this mechanism also prevented the creation of a reliable, reusable, over-the-network scanner to detect compromised systems.

The complexity of the backdoor’s implementation, involving multiple stages of obfuscation, encryption, and dynamic code injection, highlights the sophistication of the attack and the attacker’s understanding of the targeted systems and libraries.

Affected Distributions

Distro Affected version
Fedora Fedora 40 and Fedora Rawhide
Kali Linux Any Kali that was updated / installed between March 26-29
OpenSUSE OpenSUSE Tumbleweed and OpenSUSE Micro OS between March 7th and March 28th 2024 (snapshot 20240328 and earlier).
Alpine 5.6.0 prior to 5.6.1-r1

Are Cynet customers protected?

Cynet research team has developed detection to facilitate customers in assessing the risk associated with this vulnerability within their environment following by the alert name “Unauthorized File Operation Attempt” with the rule name “Linux – CVE-2024-3094 – liblzma backdoor”.

 

 

Protect Your Business from Vulnerabilities with Cynet

Don’t wait for the next exploit.
Book a demo now and stay one step ahead in your security game.

Book a Demo