Uncovering Supply Chain Attack with Code Genome Framework
Unknown
Black Hat USA 2024 · Day 1 · Briefing
Overview
In an era where software supply chain attacks are increasingly sophisticated and impactful, this Black Hat USA talk introduces the Code Genome Framework, an innovative approach developed by IBM Research to enhance software supply chain security. Presented by Jiyong and Dilung Kirat, both research scientists specializing in AI supply chain security, the session delves into the critical challenge of the "semantic gap" that exists between a software's declared metadata and its actual computational behavior. This gap is a fundamental vulnerability exploited by advanced attackers, as vividly demonstrated by recent high-profile incidents.

Key moments
- 0:00 Introduction and the 'trusting trust' problem
- 2:05 Overview of recent software supply chain attacks
- 3:00 Detailed explanation of the XZ backdoor
- 4:05 Sophisticated social engineering and stealth in XZ
- 5:00 The 'semantic gap' and current supply chain security gaps
- 6:25 Focus on post-build executable binary security
Uncovering Supply Chain Attack with Code Genome Framework
Speakers: Jiyong, Research Scientist, IBM Research; Dilung Kirat, Research Scientist, IBM Research
Conference: Black Hat USA
YouTube: https://www.youtube.com/watch?v=CTbP6L3IuW4
Overview
In an era where software supply chain attacks are increasingly sophisticated and impactful, this Black Hat USA talk introduces the Code Genome Framework, an innovative approach developed by IBM Research to enhance software supply chain security. Presented by Jiyong and Dilung Kirat, both research scientists specializing in AI supply chain security, the session delves into the critical challenge of the "semantic gap" that exists between a software's declared metadata and its actual computational behavior. This gap is a fundamental vulnerability exploited by advanced attackers, as vividly demonstrated by recent high-profile incidents.
The Code Genome Framework proposes a novel solution: to extract semantically meaningful "fingerprints," or code genomes, directly from executable binaries. By comparing these genomes, users can verify the functional equivalence of software, thereby establishing trust without solely relying on potentially compromised vendor metadata or the arduous task of manual reverse engineering. This differential analysis technique aims to provide a robust defense mechanism, offering a proactive way to detect subtle, malicious code injections that evade traditional security checks. The framework represents a significant step forward in securing the final stage of the software supply chain, where end-users interact with compiled code.
Background
▶ Watch: Introduction and the 'trusting trust' problem (0:00)
The foundational challenge in software trust, as highlighted by Ken Thompson's seminal "Reflections on Trusting Trust" Turing Award lecture, dictates that unless one builds software from scratch, including the compiler, complete trust is elusive. Modern software supply chains exacerbate this issue, forcing users to rely heavily on software vendors' reputations, development histories, and metadata such as hashes, signatures, and Software Bills of Materials (SBoMs). While these measures are crucial for integrity and provenance, they often fail to capture the true, executable behavior of the code. This inherent semantic gap between what the metadata describes and what the code actually does is the root cause of many prevalent supply chain vulnerabilities.
The speakers underscored this problem by citing several major supply chain attacks:
- SolarWinds (2020): Malicious code was injected into the software update process, affecting numerous organizations globally.
- Kaseya (2021): A compromised software update mechanism was used to distribute ransomware, impacting hundreds of businesses.
- Dependency Confusion: This technique exploits package managers to trick systems into downloading malicious packages with the same name from public repositories instead of intended private ones.
- Protestware: Malicious code embedded in popular open-source packages (e.g., an NPM package wiping files) as a form of protest.
- 3CX (March 2023): A backdoor was implanted into the 3CX desktop application for Windows and macOS, stemming from a secondary supply chain attack involving a compromised upstream library.
The most recent and sophisticated example discussed was the XZ Utils backdoor (CVE-2024-3094), discovered approximately four months prior to the talk. This incident began with a suspicious observation of high CPU usage during SSH debugging, which led to a deeper investigation by Andres Freund. The subsequent discovery revealed a highly sophisticated supply chain attack spanning three years. Attackers created multiple identities to pressure the original maintainers of the xz library, eventually becoming a trusted maintainer themselves. Over time, they introduced obfuscated, multi-chain payloads designed to hide malicious code within the liblzma library, a component of XZ Utils. The severity of this attack stems from liblzma's dependency chain: liblzma is a dependency of systemd, which in turn is a dependency of OpenSSH. This meant that if an attacker possessed the correct private key, they could remotely take full control of an affected SSH server, posing a catastrophic risk.
Existing security measures, such as vulnerability scanning, CI/CD pipeline integrity checks, and SBoM standards, are valuable but have limitations. They primarily focus on the left-hand side of the supply chain (source code, build processes, declared dependencies). However, as highlighted by incidents like XZ Utils, malicious code can be subtly injected into the final binary, bypassing these checks. Reproducible builds, while conceptually sound, are challenging to implement widely. SBoMs provide ingredients but require users to verify completeness and correctness. The Code Genome Framework specifically addresses the right-hand side of the supply chain, focusing on the executable binary that end-users ultimately receive, aiming to restore trust when vendor assurances are insufficient or compromised.
Key Findings
▶ Watch: Detailed explanation of the XZ backdoor (3:00)
The central premise of the Code Genome Framework is to overcome the fundamental semantic gap between a software's declared metadata (such as hashes, signatures, or SBoMs) and its actual executable code behavior. While metadata provides crucial information about a software's origin and components, it doesn't inherently guarantee the absence of malicious functionality, especially in the face of sophisticated supply chain attacks that inject stealthy code directly into binaries. The speakers identified this misplaced trust in metadata as a primary vulnerability.
The key finding is the development of a differential analysis approach using code genomes. Instead of relying solely on external attestations, the framework extracts intrinsic, semantically meaningful fingerprints directly from the code. These fingerprints, termed "code genomes," represent the computational essence of a function or piece of code. By comparing the code genomes of an unknown or new software version against a known-good, trusted baseline (e.g., a previous secure version), the framework can determine their functional similarity. If the genomes match, it implies that the two code segments are computationally equivalent, allowing the trust associated with the known-good baseline to be extrapolated to the new, unknown code.
This approach offers several significant advantages:
- Bridging the Semantic Gap: It directly addresses the core problem by verifying the actual behavior of the code, rather than just its external descriptors.
- Robustness against Obfuscation: The technique is designed to handle various forms of code obfuscation, such as basic block shuffling, which might alter the binary representation but not the underlying computational logic.
- Platform Agnosticism: By operating on an intermediate representation, the framework supports diverse environments, including multiple hardware architectures, compilers, and optimization levels. This broad applicability makes it a versatile tool for securing a wide range of software.
- Scalability: For average consumers or even security analysts, manually reverse engineering complex binaries to verify trust is not scalable. Code Genome provides an automated, differential method to achieve this at scale.
In essence, the Code Genome Framework provides a method to establish a chain of trust based on code equivalency, enabling users to confidently assess the integrity and expected behavior of software even when traditional trust mechanisms have been compromised.
Technical Deep Dive
▶ Watch: Sophisticated social engineering and stealth in XZ (4:05)
The Code Genome Framework is built upon a multi-stage process designed to extract semantically invariant features from executable code, regardless of superficial changes due to compilation or minor obfuscation. The core idea is to transform the code into a standardized, canonical representation before generating its unique "genome."
The process begins with the raw input, which can be either binary code (machine code) or source code. The framework leverages the Low-Level Virtual Machine Intermediate Representation (LLVM IR) as its common ground. LLVM IR is a crucial choice because it provides a compiler-agnostic, architecture-independent representation of code, making the framework highly versatile.
The technical steps are as follows:
- Lifting to Raw IR:
- If the input is source code, it is directly compiled into raw LLVM IR.
- If the input is binary code, it is first lifted into raw LLVM IR. This involves disassembling the machine code and converting it into the LLVM IR format, a process that normalizes architectural specifics.
- Canonicalization Process:
- This is a critical stage implemented as an LLVM pass. The goal of canonicalization is to reduce the raw IR into a simplified, essential form that captures only the core computational logic, discarding elements that do not affect the function's semantic behavior.
- The primary stage within canonicalization is optimization. The framework leverages decades of research in compiler optimization techniques. These optimization passes are applied to the function's IR to:
- Remove redundant instructions.
- Simplify expressions.
- Eliminate dead code.
- Normalize control flow constructs.
- By applying these optimizations, the framework ensures that two functions that are semantically equivalent but compiled with different compilers, optimization levels, or even subjected to certain types of obfuscation (e.g., basic block reordering) will yield the same canonical IR. This is because the optimization passes reduce both to their minimal, functionally identical form. This step is crucial for achieving code equivalency, forming the basis of the trust chain.
- Feature Extraction (Genome Generation):
- Once the canonical IR for a function is obtained, the final step is to generate its unique "code genome" or feature vector. The talk specifically mentions using a tool called Signal for this purpose.
- The Signal approach is based on signal processing. The canonical IR, which is essentially a sequence of instructions, is conceptually converted into an "image."
- Gabor filters are then applied to this "image." Gabor filters are widely used in image processing and computer vision for texture analysis and feature extraction, as they are effective at capturing localized frequency and orientation information. In this context, they are used to extract robust feature vectors that represent the unique computational signature of the canonical IR. These feature vectors are the ultimate "gene" for that specific code function.
By following this precise sequence of lifting, canonicalization, and feature extraction, the Code Genome Framework produces a compact, semantically meaningful fingerprint for any given code segment. These genomes can then be efficiently compared using standard similarity metrics to ascertain functional equivalence, providing a powerful mechanism to detect even subtle, malicious alterations in software binaries.
Demo / Proof of Concept
▶ Watch: The 'semantic gap' and current supply chain security gaps (5:00)
While the talk provided a clear and detailed explanation of the Code Genome Framework's architecture and processing pipeline, including a concrete example illustrating the transformation from machine code to raw IR and then canonical IR, a live demonstration or explicit proof-of-concept showing the framework actively detecting a specific malicious binary or comparing two versions of software was not explicitly detailed in the transcript. The speakers used the XZ Utils backdoor as a motivating example to highlight the need for such a framework, implying its potential applicability rather than presenting a direct demonstration of it being used to uncover that specific attack. The discussion focused on the theoretical and technical underpinnings of how the "code genome" is generated and how it could be used for differential analysis.
Defensive Implications
▶ Watch: Focus on post-build executable binary security (6:25)
The Code Genome Framework offers profound defensive implications, fundamentally shifting the paradigm of software trust from external attestations to intrinsic code behavior.
- Proactive Detection of Sophisticated Attacks: By identifying the semantic gap as a primary exploit vector, the framework enables the proactive detection of advanced supply chain attacks like XZ Utils. These attacks often involve subtle, obfuscated code injections designed to bypass traditional signature-based or metadata-focused security checks. Code Genome’s ability to discern functional equivalence despite superficial changes means it can catch malicious payloads that are cleverly hidden within legitimate software updates.
- Enhanced Software Integrity Verification: For end-users and organizations, the framework provides a robust method to verify the integrity of executable binaries. Instead of solely trusting vendor certificates or SBoMs, which can be compromised or manipulated, users can now compare the code genomes of received software against known-good baselines (e.g., a previous trusted version or a clean build). Any deviation in the genome would signal a potential compromise, even if traditional hashes or signatures remain valid due to partial tampering.
- Complementing Existing Security Standards: Code Genome doesn't replace standards like SBoMs but rather complements them. While SBoMs provide a list of ingredients, Code Genome verifies the functional correctness of those ingredients as they appear in the final binary. This adds a crucial layer of assurance, ensuring that the components listed in an SBoM behave as expected.
- Differential Analysis for Updates: Software updates are a common vector for supply chain attacks. The framework's differential analysis capability is particularly powerful here. Before deploying an update, organizations can generate code genomes for the new version and compare them against the trusted previous version. Any unexpected functional changes, especially in critical components, can be flagged for deeper investigation, significantly reducing the attack surface introduced by updates.
- Robustness Against Compiler and Environmental Variations: By leveraging LLVM IR and its canonicalization process, the framework is inherently resilient to variations introduced by different compilers, optimization levels, or target architectures. This ensures that legitimate builds, even if produced under slightly different conditions, will still yield matching code genomes, minimizing false positives and making the system practical for diverse software ecosystems.
- Reducing Reliance on Manual Reverse Engineering: For complex binaries, manual reverse engineering to uncover malicious functionality is time-consuming, expensive, and requires specialized expertise. Code Genome provides an automated, scalable alternative, allowing security teams to quickly identify suspicious functional changes without the need for extensive manual analysis, thereby accelerating incident response.
- Integration into CI/CD Pipelines: The automated nature of genome generation and comparison makes it suitable for integration into Continuous Integration/Continuous Deployment (CI/CD) pipelines. This allows for continuous, automated security checks on every build, ensuring that malicious code is detected as early as possible in the development lifecycle before it reaches end-users.
In summary, the Code Genome Framework empowers defenders with a powerful, semantic-aware tool to establish and maintain trust in software binaries, offering a vital defense against the evolving landscape of supply chain attacks.
Key Takeaways
- Supply chain attacks exploit the semantic gap: Traditional metadata (hashes, signatures, SBoMs) often fail to capture the true, executable behavior of code, creating a critical vulnerability exploited by sophisticated attackers.
- Code Genome bridges this gap via functional fingerprinting: The framework extracts semantically meaningful "code genomes" that represent the core computational logic of software functions, providing an intrinsic measure of trust.
- LLVM IR and canonicalization are central to the approach: By converting code to LLVM IR and applying optimization-based canonicalization, the framework achieves resilience against variations from different compilers, architectures, and certain obfuscation techniques.
- Differential analysis enables trust in unknown binaries: Comparing the code genomes of a new or unknown binary against a known-good baseline allows for the verification of functional equivalence, extending trust without relying solely on external attestations.
- Robust against obfuscation and diverse environments: The framework's design handles various obfuscation methods and supports multiple architectures, compilers, and optimization levels, making it broadly applicable.
- Offers proactive defense against sophisticated attacks: Code Genome provides a powerful tool for detecting subtle, malicious code injections that evade traditional security checks, as demonstrated by the challenges posed by incidents like the XZ Utils backdoor.
About the Speaker(s)
The talk was delivered by Jiyong and Dilung Kirat, both accomplished Research Scientists at IBM Research. Their work is primarily focused on AI supply chain security, utilizing advanced AI techniques to bolster the security posture of complex software supply chains. Additionally, they explore the broader security implications of AI itself. This presentation builds upon their prior work, notably their 2018 Black Hat talk, "Deep Locker," which explored how malicious actors could leverage AI and machine learning to craft advanced threats. In this current talk, they demonstrated how similar AI/ML technologies can be repurposed for defensive measures, specifically in the context of detecting sophisticated supply chain attacks.