Project 0xA11C: Deoxidizing the Rust Malware Ecosystem
Unknown
Black Hat USA 2024 · Day 1 · Briefing
Overview
The proliferation of malware written in modern, memory-safe languages like Rust presents an escalating challenge for reverse engineers and cybersecurity defenders. This talk, "Project 0xA11C: Deoxidizing the Rust Malware Ecosystem," delivered by Juan Andre Herrera (Jags) from SentinelOne and Nicole Fischman from Interzer, tackles this critical issue head-on. The speakers articulate a growing frustration within the reverse engineering community regarding the increasing difficulty of analyzing binaries compiled from contemporary programming languages. They argue that traditional reverse engineering methodologies and tools are ill-equipped to handle the complexities introduced by Rust, leading to a "thriving malware ecosystem" that operates with relative impunity.

Key moments
- 0:00 Introduction and the challenge of reversing Rust
- 2:00 Reversing culture evolution: from assembly to decompilers
- 3:00 Modern language challenges: huge binaries, custom conventions
- 4:40 The Go experience: a promising precedent for Rust
- 5:00 Detailed Go reversing difficulties: static linking, stack issues
- 6:20 Introduction to Rust: features, memory safety, borrow checker
- 8:00 Rust's data-rich binaries and rapid development challenges
Project 0xA11C: Deoxidizing the Rust Malware Ecosystem
Speakers: Juan Andre Herrera (Jags), Research Lead, SentinelOne; Nicole Fischman, Security Researcher, Interzer
Conference: Black Hat USA
YouTube: https://www.youtube.com/watch?v=cMIhIARmNfU
Overview
The proliferation of malware written in modern, memory-safe languages like Rust presents an escalating challenge for reverse engineers and cybersecurity defenders. This talk, "Project 0xA11C: Deoxidizing the Rust Malware Ecosystem," delivered by Juan Andre Herrera (Jags) from SentinelOne and Nicole Fischman from Interzer, tackles this critical issue head-on. The speakers articulate a growing frustration within the reverse engineering community regarding the increasing difficulty of analyzing binaries compiled from contemporary programming languages. They argue that traditional reverse engineering methodologies and tools are ill-equipped to handle the complexities introduced by Rust, leading to a "thriving malware ecosystem" that operates with relative impunity.
The core of their presentation is a candid exploration of why Rust binaries are so challenging to analyze, drawing parallels with past struggles encountered with Go malware. They then introduce Project 0xA11C, an initiative aimed at developing practical, script-based solutions for IDA Pro (and potentially other platforms like Binary Ninja) to automate and streamline the reverse engineering of Rust malware. This project seeks to "deoxidize" the ecosystem by providing analysts with the necessary tools to cut through the noise of large, statically linked binaries and identify user-generated malicious code, ultimately making Rust-based threats more transparent and defensible.
This talk is particularly significant because it addresses a fundamental shift in the malware development landscape. As threat actors increasingly adopt modern, performant, and cross-platform languages like Rust—often to evade detection and complicate analysis—the security community must adapt. By identifying the specific pain points and proposing concrete, open-source solutions, Herrera and Fischman aim to empower reverse engineers, enabling more efficient threat intelligence gathering and more robust defensive strategies against the next generation of sophisticated malware.
Background
▶ Watch: Introduction and the challenge of reversing Rust (0:00)
The journey of reverse engineering has been one of continuous adaptation, from the early days of assembly-level analysis to the more abstract challenges posed by high-level languages. Juan Andre Herrera reflects on a "toxic reversing culture" where reliance on disassemblers was seen as the pinnacle of skill, while decompilers were derided as tools for "rich noobs." However, as programming languages evolved, introducing multiple layers of abstraction, the necessity of decompilers became undeniable. Languages like C++ and Delphi, with their object-oriented paradigms and complex structures, already pushed the limits of low-level analysis. Modern languages, however, have introduced an entirely new set of obstacles.
The speakers highlight a trend of "things going from bad to worse" for reverse engineers. Every few months, a new programming language or paradigm emerges, often featuring novel memory management, garbage collection, or reference handling. While beneficial for developers, these innovations create immense headaches for analysts. Key challenges include:
- Huge Binaries: Often statically linked, incorporating entire libraries, resulting in massive executable sizes that dwarf the actual malicious code. A simple "Hello World" in Go, for instance, could be 5 megabytes.
- Static Link Code: Thousands or tens of thousands of functions from standard libraries obscure the relatively few user-generated functions, making it nearly "impossible to find the user generated code."
- Unconventional/Custom Calling Conventions: Modern compilers and languages frequently deviate from standard calling conventions, making argument tracing and function prototype reconstruction extremely difficult. Rust, in particular, allows developers to define custom calling conventions for individual functions, further complicating analysis.
- Active Development Communities: While beneficial for language evolution, rapid, arbitrary changes to internal structures, memory layouts, and compilation artifacts break existing reverse engineering tools and assumptions without warning.
- Tool Limitations: Existing tools struggle with type reconstruction, complex function prototypes, consistent argument tracing (especially with stack references and scope-breaking behaviors), and the recovery of structures, classes, and methods.
This confluence of factors leads to a "thriving malware ecosystem" when nobody is effectively looking. The speakers draw a direct parallel to the rise of Go malware, which saw an explosion of APTs and ransomware that were notoriously difficult to reverse engineer. Go presented issues such as handling multiple return values, complex type recovery, vast amounts of static link functions, and problems with stack reinterpretation in tools like IDA Pro, often preventing successful decompilation ("F5 reversing"). The key insight, however, was that despite these difficulties, the Go ecosystem eventually yielded to targeted reverse engineering efforts, providing a blueprint for tackling Rust.
Key Findings
▶ Watch: Modern language challenges: huge binaries, custom conventions (3:00)
The central premise driving Project 0xA11C is a critical observation about how modern programming languages, particularly Rust, handle data within compiled binaries. Contrary to older paradigms where developers might strive to strip all non-essential data from the final executable, newer languages often retain a significant amount of data. While references to this data might be removed or obscured, the underlying information persists. This insight forms the foundation of their "magic" – the ability to leverage this persistent data to reconstruct crucial context for reverse engineering.
The speakers illustrate this finding with a compelling example: their analysis of the Desert Blade Wiper, a Russian-developed Rust malware used in the early stages of the invasion of Ukraine. By applying a series of custom scripts and methodologies, they achieved a dramatic reduction in analytical overhead. Within a minute of applying these techniques, a binary that initially presented 2400 unidentified functions was transformed, revealing only eight user-generated functions with everything else properly labeled. This striking contrast highlights the potential for their approach to cut through the immense noise generated by statically linked Rust binaries, allowing analysts to quickly focus on the truly relevant malicious code.
This success with the Desert Blade Wiper, and prior positive experiences with Go malware, validates their hypothesis: even if compilers strip symbols and obfuscate control flow, enough metadata often remains within the binary to aid in reverse engineering. The "data stays there," as Herrera puts it, and it's this persistent data that Project 0xA11C aims to exploit. By developing intelligent scripts that can parse and interpret these hidden artifacts, they can automate the tedious process of identifying library functions, reconstructing data structures, and distinguishing legitimate boilerplate from malicious functionality. This effectively "deoxidizes" the Rust malware, making its inner workings accessible and understandable to analysts.
Technical Deep Dive
▶ Watch: The Go experience: a promising precedent for Rust (4:40)
Rust's design, while lauded for its performance and memory safety, inadvertently creates a formidable barrier for reverse engineers. As an open-source, cross-compiling language with a strict compiler that enforces memory safety through an ownership system and borrow checker (and notably, no garbage collector), Rust prevents many common C/C++ vulnerabilities at compile time. Its Cargo dependency manager is powerful, and its community is highly active, releasing new versions frequently—sometimes nightly. These features, however, become significant impediments for malware analysis.
The technical challenges in reversing Rust binaries can be broken down into several key areas:
- Binary Size and Static Linking: Rust binaries are notoriously large, even when stripped of symbols. This is primarily due to Rust's preference for static linking, where all necessary libraries and runtime components are bundled directly into the executable. This results in binaries containing "thousands and tens of thousands of functions" that are part of the Rust standard library or third-party crates, overwhelming analysts trying to locate the actual malicious logic.
- String Overload and Encryption: While Rust binaries contain a plethora of strings, most are uninteresting or related to compiler internal messages, standard library functions, or debugging information. Crucially, "most of the strings that are interesting are encrypted," further hindering quick analysis.
- Complex Functions and Stack Variables: Rust functions can be quite large and frequently utilize many stack variables. This complexity, combined with the lack of clear demarcation between library and user code, makes manual analysis excruciatingly slow and error-prone.
- Custom Calling Conventions: Unlike languages with more rigid calling conventions, Rust supports various conventions, and developers can choose a different one for each function. This flexibility, while powerful for developers, is a nightmare for reverse engineers, as it makes consistent argument identification and function prototype reconstruction nearly impossible for automated tools.
- Rapid Language Evolution: The "very strong community" that releases "new versions not every month, there is also new version every night" means that internal structures, compilation artifacts, and even the low-level representation of Rust code can change rapidly. This constant flux breaks assumptions made by reverse engineering tools and requires continuous updates, which most commercial tools cannot keep pace with.
To address these profound challenges, Project 0xA11C focuses on developing a suite of scripts (rather than full-fledged plugins) primarily for IDA Pro, with an eye towards Binary Ninja and other platforms. The emphasis on scripts is strategic: they are easier to develop, maintain, and share within a rapidly evolving ecosystem. The project's core objectives include:
- Recovering Panic Paths: Rust's error handling mechanism,
panic!, provides valuable information about potential failure points and logic paths. Scripts to recover these paths can expose critical program flow and error conditions. - Placing Slices and Structs: Rust's slices and structs are fundamental data types. Accurately identifying and reconstructing these within the binary is crucial for understanding data manipulation and program logic. The speakers note the difficulty in creating a "generalized structure creator" but highlight that manual entry of C-style struct definitions into IDA Pro is currently possible.
- Inferring Dependencies with Versions: Understanding which Rust crates (libraries) and their specific versions are used in a binary can provide immense context. This helps in identifying known vulnerabilities, understanding intended functionality, and differentiating between standard library code and custom malicious implementations.
- "Dirty Stuff" and Community Contributions: The project also aims to provide "harnesses to be able to compile things" and "create signature files." These are tools that assist in generating reference binaries or signatures for known Rust components, which can then be used to identify and filter out boilerplate code in unknown samples. The speakers acknowledge the difficulty in standardizing such setup across different environments and invite community contributions, even mentioning their internal ChatGPT bot for IDA Pro stuff, "Gabo RE," as a resource for exploring these challenges.
The long-term vision for Project 0xA11C is to create a robust, community-driven framework that systematically deconstructs Rust binaries, providing reverse engineers with the context they desperately need to analyze complex malware effectively.
Demo / Proof of Concept
▶ Watch: Introduction to Rust: features, memory safety, borrow checker (6:20)
While the talk did not feature a live, interactive demonstration in the traditional sense, the speakers presented a compelling proof of concept through the case study of the Desert Blade Wiper. This real-world example served as a powerful illustration of Project 0xA11C's effectiveness.
The Desert Blade Wiper, a Rust-based malware deployed against targets in Ukraine, initially presented as an overwhelmingly complex binary. For a reverse engineer using conventional tools, it would appear as a monolithic executable containing thousands of undifferentiated functions. However, by applying their nascent techniques and scripts, the Project 0xA11C team was able to dramatically simplify the analytical landscape.
As highlighted by Herrera, within "a minute of just applying a bunch of scripts," the binary was transformed from showing 2400 unidentified functions to revealing only eight user-generated functions, with "everything else labeled properly." This stark reduction in noise is the essence of their proof of concept. It demonstrates that by intelligently parsing the persistent data within Rust binaries, even when stripped, it is possible to:
- Distinguish Library Code from User Code: The vast majority of the 2400 functions were likely part of the Rust standard library or statically linked third-party crates. The scripts successfully identified and labeled these, effectively filtering them out.
- Highlight Malicious Logic: The remaining eight functions represent the core, user-written malicious logic of the wiper. This allows analysts to immediately focus their efforts on understanding the specific actions and capabilities of the malware without being bogged down by irrelevant boilerplate.
- Accelerate Analysis: The time frame of "within a minute" underscores the potential for significant acceleration in malware analysis workflows, a critical factor when responding to active threats.
This example serves as a powerful validation of the "data stays there" hypothesis and the practical utility of Project 0xA11C's script-based approach. It illustrates how automated context recovery can fundamentally change the efficiency and feasibility of reversing modern, complex binaries like those compiled from Rust.
Defensive Implications
▶ Watch: Rust's data-rich binaries and rapid development challenges (8:00)
The insights and tools presented in "Project 0xA11C" carry significant defensive implications for cybersecurity professionals. As threat actors increasingly gravitate towards Rust for its performance, cross-platform capabilities, and inherent obfuscation benefits for reverse engineers, the ability to effectively analyze Rust malware becomes paramount.
- Adaptation of Reverse Engineering Capabilities: Defenders, particularly malware analysts and threat intelligence teams, must recognize that traditional reverse engineering tools and methodologies are no longer sufficient for modern languages like Rust. Organizations need to invest in adapting their RE capabilities, either by integrating tools like those proposed in Project 0xA11C or by fostering internal expertise in Rust's unique compilation and runtime characteristics.
- Enhanced Threat Intelligence: Faster and more accurate analysis of Rust malware directly translates to better threat intelligence. By quickly identifying the core malicious functions, understanding data structures, and inferring dependencies, defenders can develop more precise signatures, improve detection rules, and gain deeper insights into adversary tactics, techniques, and procedures (TTPs). The ability to go from 2400 unidentified functions to 8 user-generated ones in minutes is a game-changer for incident response.
- Proactive Tool Development and Community Engagement: The talk implicitly calls for a more proactive approach to tool development within the defensive community. Relying solely on commercial tools that lag behind rapid language evolution is no longer viable. Supporting open-source initiatives like Project 0xA11C, contributing to its development, or developing similar in-house solutions is crucial. The mention of "Gabo RE," a ChatGPT bot for IDA Pro, also points towards leveraging AI/ML for automated assistance in RE tasks.
- Understanding of Rust's Defensive Strengths and Weaknesses: While Rust offers memory safety benefits that reduce certain classes of vulnerabilities, its complexity in reverse engineering can be exploited by attackers. Defenders need to understand both sides of this coin. For example, while
panic!paths can be recovered as an analytical aid, attackers might also leverage Rust's robust error handling to create more resilient malware. - Training and Skill Development: Security teams should consider training their analysts in Rust programming fundamentals, even if not for development, but for a deeper understanding of its compilation processes, ownership model, and standard library. This knowledge will significantly aid in leveraging specialized Rust RE tools and interpreting their output.
In essence, Project 0xA11C is a clarion call for the defensive community to "deoxidize" its own capabilities. By embracing new methodologies and tools tailored to the specifics of Rust, defenders can reduce the operational cost of analyzing these increasingly prevalent threats, turning what was once an "unmitigated disaster" into a manageable and actionable process.
Key Takeaways
- Rust malware is a growing and challenging threat: Threat actors are increasingly adopting Rust, as seen with APTs like Wild Card (Rustdown component), Rustbucket, and various ransomware, largely due to its performance, cross-platform capabilities, and the difficulty it poses for traditional reverse engineering tools.
- Traditional RE tools and methodologies are struggling: Modern languages like Rust introduce significant complexities, including huge statically linked binaries, custom calling conventions per function, rapid language evolution, and an abundance of unhelpful strings, which overwhelm existing reverse engineering platforms like IDA Pro.
- The key to reversing Rust lies in leveraging persistent data: Despite attempts to strip symbols or obfuscate, modern compilers often leave substantial data within the binary. Project 0xA11C's core insight is to exploit this data to reconstruct context and identify relevant code.
- Project 0xA11C aims to provide practical, script-based solutions: The initiative focuses on developing open-source scripts for IDA Pro (and potentially Binary Ninja) to automate tasks like recovering panic paths, placing slices and structs, and inferring dependencies with versions, thereby making Rust malware analysis more efficient.
- Dramatic reduction in analysis effort is achievable: As demonstrated with the Desert Blade Wiper, their methods can reduce thousands of unidentified functions to a handful of user-generated functions, allowing analysts to quickly pinpoint malicious logic.
- Community collaboration and continuous adaptation are crucial: The rapid evolution of Rust necessitates ongoing development and community contributions to keep reverse engineering tools and techniques effective against new malware variants.
About the Speaker(s)
Juan Andre Herrera, known as Jags, is the Research Lead at SentinelOne, a prominent cybersecurity company specializing in endpoint protection. In addition to his industry role, Jags also contributes to academic research at the El Peruvich Institute. His work often focuses on cutting-edge threats and advanced reverse engineering challenges, a background that informed his deep understanding of the complexities presented by modern programming languages in malware analysis.
Nicole Fischman is a Security Researcher at Interzer. This presentation marked her first appearance at Black Hat USA, highlighting her emerging contributions to the field of cybersecurity research. Her work on discovering the Wild Card APT, which notably switched to using Rust for some of its components (such as Rustdown), directly led to the collaborative effort and insights presented in Project 0xA11C.