XRP Raid Protector: Killing A Critical Bug Worth 40 Billion Dollars
Haoyu Yang (Security Researcher · Tencent)
HITBSecConf2023 - Amsterdam · Day 1 · Track 2
Overview
In a groundbreaking presentation at HITB Amsterdam, Haoyu Yang, a security researcher at Tencent Security Xuanwu Lab, unveiled a critical vulnerability within the core infrastructure of the XRP Ledger. Titled "XRP Raid Protector: Killing A Critical Bug Worth 40 Billion Dollars," the talk detailed an 8-year-old memory corruption bug in rippled, the official C++ node server implementation for the XRP Ledger. This vulnerability, if exploited, could lead to a full chain takeover, allowing attackers to achieve remote command execution (RCE) on node servers and potentially manipulate the entire blockchain network.

Key moments
- 0:00 Introduction to XRP Ledger and critical bug
- 7:00 Discovering the signed/unsigned integer vulnerability
- 13:00 Achieving Denial of Service (DoS) via IO service deadlock
- 19:00 Sophisticated heap spray technique using TMManifest messages
- 24:20 Arbitrary Code Execution and network compromise potential
- 28:00 Live demonstration of the XRP Ledger exploit
- 30:52 Bug bounty details and audience Q&A
XRP Raid Protector: Killing A Critical Bug Worth 40 Billion Dollars
Speakers: Haoyu Yang (Security Researcher, Tencent)
Conference: HITB Amsterdam
YouTube: https://www.youtube.com/watch?v=c9zZ3aMAyDs
Overview
In a groundbreaking presentation at HITB Amsterdam, Haoyu Yang, a security researcher at Tencent Security Xuanwu Lab, unveiled a critical vulnerability within the core infrastructure of the XRP Ledger. Titled "XRP Raid Protector: Killing A Critical Bug Worth 40 Billion Dollars," the talk detailed an 8-year-old memory corruption bug in rippled, the official C++ node server implementation for the XRP Ledger. This vulnerability, if exploited, could lead to a full chain takeover, allowing attackers to achieve remote command execution (RCE) on node servers and potentially manipulate the entire blockchain network.
The significance of this discovery cannot be overstated. The XRP Ledger, underpinning the popular cryptocurrency XRP, is a major player in the crypto ecosystem, often ranking among the top digital assets by market capitalization. A vulnerability of this magnitude, capable of compromising the integrity and control of such a prominent blockchain, poses a severe threat not only to XRP holders but also to the broader decentralized finance landscape. Yang's work highlights the critical importance of scrutinizing the underlying infrastructure of blockchain protocols, moving beyond application-level security to address fundamental memory safety issues in core node implementations.
Background
▶ Watch: Introduction to XRP Ledger and critical bug (0:00)
The XRP Ledger (XRPL) is a distributed ledger technology that serves as the backbone for the XRP token. Developed and open-sourced by Ripple, it functions as a Layer 1 blockchain protocol, distinguished by several key features. These include Trust Lines and Rippling, which facilitate the issuance and transfer of non-native currencies, and robust on-chain exchange features for token trading. Notably, the XRPL eschews smart contract functionality, a design choice intended to reduce the attack surface often associated with complex contract logic. Its consensus algorithm is a Byzantine Fault Tolerant (BFT) mechanism known as the Ripple Protocol Consensus Algorithm (RPCA), which relies on a network of validating servers to advance the ledger history.
The network comprises two main types of participants: tracking servers, which distribute transactions and respond to queries, and validators, which perform tracking functions while also contributing to ledger advancement. The core software powering these nodes is rippled, written in C++ and heavily leveraging libraries like Boost and ASIO. As the sole server implementation composing the XRPL network, rippled is a critical component whose security directly impacts the entire ecosystem. Haoyu Yang, a former CTF player with a keen interest in blockchain and application security, was drawn to rippled due to its C++ codebase, recognizing the potential for memory corruption vulnerabilities – a common class of bugs in such low-level implementations. His investigation focused on uncovering these fundamental flaws that could undermine the integrity of a system designed for trustless operation.
Key Findings
▶ Watch: Achieving Denial of Service (DoS) via IO service deadlock (13:00)
The central discovery was an 8-year-old memory corruption vulnerability within the rippled node server, specifically an out-of-bounds (OOB) write that could be triggered remotely. This bug stemmed from an integer overflow during the conversion of a network-controlled unsigned int field into a signed int within a critical internal object. This type confusion, combined with insufficient validation, allowed an attacker to write outside the intended memory boundaries of a fixed-size array within the LiveCache component.
Initially, this OOB write was identified as a Denial of Service (DoS) primitive. By manipulating the hops field in an Endpoint message, an attacker could cause a deadlock in boost::asio::io_service, leading to the rippled server hanging for 10 minutes before an automatic restart. However, the true severity of the bug was realized when Yang escalated this primitive to achieve Remote Code Execution (RCE). This was accomplished through virtual function table (VFT) hijacking, where the OOB write was leveraged to corrupt a virtual function pointer, redirecting program execution to attacker-controlled memory. To reliably place the malicious payload, a sophisticated heap spraying technique was developed, exploiting the memory allocation patterns of TMManifest messages. This chain of vulnerabilities ultimately allowed for arbitrary code execution on compromised rippled nodes, presenting a path to a full chain takeover of the XRP Ledger.
Technical Deep Dive
▶ Watch: Sophisticated heap spray technique using TMManifest messages (19:00)
Yang initiated his security analysis by examining potential attack vectors for rippled. He identified two primary candidates: the RPC service and the P2P protocol. Given that the RPC service is not always exposed publicly, he opted to focus on fuzzing the P2P protocol, which is universally accessible for node communication. The rippled P2P communication begins with an HTTP handshake to exchange basic information and establish a TLS key for encryption. Following this, a protobuf-based P2P communication takes over, handling all chain-related data like transactions, validations, blocks, and peers. The presence of approximately 25 types of P2P messages, each with a protobuf schema definition, greatly facilitated the fuzzing process. Yang quickly set up a structure-aware fuzzer based on libFuzzer, a tool well-suited for such structured inputs.
The vulnerability was ultimately located in the PeerFinder component, specifically within its LiveCache sub-component. The PeerFinder is responsible for discovering and connecting to other nodes. When a peer comes online, it connects to hard-coded bootstrapping nodes and then receives Endpoint messages from connected peers, storing this information. The LiveCache stores incoming Endpoint information in memory, while the BootCache stores successfully connected peer information on disk.
The bug resided in the insert function of the LiveCache. This function adds Endpoint information, which includes a hops field representing the network distance between peers. The LiveCache uses a member variable m_list to store these endpoints. m_list is defined as an std::array with a fixed length, where each element is a boost::list<Endpoint>. In essence, m_list is an array of eight double-linked lists, each intended to store endpoints with corresponding hops values.
The critical flaw emerged from an integer overflow during type conversion. The hops field, as received in the TM_Endpoint protobuf message, is an unsigned int. However, when this message is transformed into an internal Endpoint object, the hops field within the Endpoint class is defined as a signed int. Crucially, there was insufficient verification before or after this transformation. An attacker could send an Endpoint message with a specially crafted negative hops value (e.g., 0xFFFFFFFF as an unsigned int). When this value is cast to a signed int, it becomes -1. This negative hops value was then used as an index into the m_list array, resulting in an out-of-bounds (OOB) write to m_list[-1], accessing memory before the m_list array. Although there was a check to ensure hops was not larger than MAX_HOPS, preventing positive overflows, the negative indexing was overlooked.
The memory layout of rippled played a significant role in the exploitability. The LiveCache object is a member of MLogic, which is part of PeerFinder, which is part of Overlay, which is finally a member of ApplicationImp. The ApplicationImp object is allocated only once at program initialization and remains at a fixed address throughout the rippled process's lifetime. This meant the memory region immediately preceding m_list was stable and contained other predictable objects belonging to the same large ApplicationImp object.
The OOB write itself involved a push_front operation on a boost::list. A typical push_front operation in a double-linked list involves updating prev and next pointers of the new node and existing nodes. By performing push_front on m_list[-1], the attacker could effectively manipulate pointers in an arbitrary memory location. This provided a powerful 2-pointer dereference write primitive: the ability to write to (root->next->prev) and (fake_prev->next). This primitive significantly extended the attacker's control over memory writes.
To identify exploitable targets for this primitive, Yang developed a GDB script to locate potential addresses where a 2-pointer dereference write could occur without immediately triggering a segmentation fault. This yielded over 20 "gadget" addresses. Among these, he quickly discovered a Denial of Service (DoS) gadget. By targeting a pointer within boost::asio::io_service, specifically its m_impl pointer, a malicious Endpoint message could replace this pointer with a fixed, attacker-controlled object. This caused a deadlock because a spin lock in the original m_impl object was never released. While a separate monitoring thread would detect the deadlock and restart the process after 10 minutes, this still constituted a significant DoS attack.
To escalate to Remote Code Execution (RCE), Yang focused on virtual function table (VFT) hijacking. He found gadgets where readable pointers could be replaced by the address of the Endpoint object itself. If a virtual function call was subsequently triggered on such a corrupted object, the control flow could be hijacked, redirecting execution to attacker-controlled data within the Endpoint object. However, a major challenge was reliably placing the desired payload in memory for the VFT hijack.
The Endpoint object's IP address field, a natural payload holder, had strict input validations. Other internal objects created by P2P messages were under tight memory management and often freed quickly (e.g., Endpoint objects freed in 30 seconds). Transaction objects, while allowing arbitrary bytes in their condition field, were limited to 250 per node and would be broadcast across the network, leading to unpredictable side effects.
Yang's breakthrough for heap spraying came from analyzing the TMManifest message in the protobuf definition. This message contains a bytes field, which is a variable-length array. Protobuf handles repeated fields of bytes using RepeatedPtrField<ArenaStringPtr>, which behaves similarly to std::vector and can point to std::string objects. Crucially, debugging revealed that the buffers holding these bytes fields were allocated on the glibc Heap, the same heap as the Endpoint objects. This made TMManifest an ideal candidate for heap spraying.
Since direct allocation/deallocation on command for creating memory holes was not feasible, Yang devised a clever workaround:
- Send two large
TMManifestmessages (approximately 64MB each), causing therippledprocess to allocate over 80,000 buffers for each message. This creates a specific memory layout. - Just as the second 64MB
TMManifestmessage is about to be freed, send the maliciousEndpointmessage. This allocates theEndpointobject's buffer. - Immediately send two more large
TMManifestmessages. These new allocations fill the memory regions, strategically placing the attacker's payload (for VFT hijacking) directly below the newly allocatedEndpointobject.
This technique, while less precise, achieved a respectable 30% success rate. Once the specific virtual function call was triggered, the control flow was hijacked, leading to Arbitrary Code Execution (ACE).
Demo / Proof of Concept
▶ Watch: Live demonstration of the XRP Ledger exploit (28:00)
The presentation included a live demonstration of the exploit, showcasing both the DoS and RCE capabilities. The setup involved four devices: two mobile phones displaying wallet statuses (victim and attacker) and two laptops. One laptop ran a local XRP Ledger network with three rippled node servers in separate virtual machines, while the other laptop was used to execute the attack.
The demo successfully illustrated the ability to compromise a rippled node, leading to arbitrary code execution. Following the successful RCE, Yang elaborated on the potential real-world impact. He estimated that a single attacker, using this vulnerability, could compromise one rippled node server in approximately 12 minutes, generating about 1GB of outgoing network traffic. Escalating this to the entire XRP Ledger network, a single machine could compromise all nodes within nine days. However, this process could be significantly accelerated by using multiple attacking machines in parallel.
Yang then brainstormed various malicious profit-making scenarios for an attacker who achieves a full chain takeover:
- Stealing valid credentials: Compromised servers might store sensitive information.
- Stealing funds from exchanges: By controlling their
ripplednode servers, attackers could manipulate exchange operations. - Double-spending attacks: The ability to alter ledger history could enable transactions to be spent multiple times.
- Hijacking critical logic: Attackers could alter transaction verification logic, allowing illegal transactions to be accepted, or modify balance calculation logic to covertly increase specific addresses' balances over time.
The demonstration underscored the severe implications of such a fundamental vulnerability in a decentralized system like the XRP Ledger, where control over a majority of nodes could lead to catastrophic financial and trust implications.
Defensive Implications
▶ Watch: Bug bounty details and audience Q&A (30:52)
The discovery and successful exploitation of this critical 8-year-old bug in rippled carry profound defensive implications for all stakeholders in the XRP Ledger ecosystem and, by extension, for the broader blockchain community.
For developers maintaining core blockchain infrastructure written in C++ or similar low-level languages, this vulnerability serves as a stark reminder of the perils of memory unsafety. Strict adherence to secure coding practices is paramount. This includes:
- Rigorous input validation: Especially for integer types, developers must implement comprehensive checks to prevent integer overflows and underflows, particularly when converting between
signedandunsignedtypes, or between different integer sizes. - Boundary checks: Any operation involving array indexing or buffer manipulation must include explicit boundary checks to prevent out-of-bounds reads/writes.
- Safe integer libraries: Employing libraries or language features that prevent or detect integer overflows can mitigate such risks.
- Memory-safe languages: While
rippledis in C++, considering Rust or similar memory-safe languages for new critical components can drastically reduce the attack surface for memory corruption bugs. - Code Audits and Fuzzing: Regular, in-depth security audits and continuous structure-aware fuzzing (as demonstrated by Yang) are essential practices to uncover latent vulnerabilities, especially in complex P2P protocols with intricate message parsing.
For XRP Ledger node operators and exchanges running rippled servers, immediate and proactive measures are crucial:
- Prompt Patching: Ensure all
rippledinstances are updated to the latest patched version. The talk mentioned the bug was "fixed silently," indicating that updates would contain the remediation. - Network Segmentation: Isolate
ripplednodes within secure network segments, limiting their exposure to untrusted networks. - Intrusion Detection/Prevention Systems (IDPS): Implement IDPS to monitor for unusual P2P traffic patterns or known exploit signatures. While the specific exploit might be new, anomalies in message sizes or content could indicate an attack attempt.
- Least Privilege: Run
rippledprocesses with the minimum necessary privileges to reduce the impact of a successful compromise. - Regular Backups: Maintain robust backup and recovery strategies for ledger data.
More broadly, this research underscores the often-underestimated security risks associated with P2P protocols in decentralized networks. While application-level smart contract security often garners significant attention, vulnerabilities in the underlying network communication layer can be equally, if not more, devastating, leading to fundamental compromises of the entire network's integrity. The potential for a full chain takeover from a single memory corruption bug highlights the need for a holistic security approach that covers every layer of the blockchain stack, from hardware to application logic.
Key Takeaways
- A critical, 8-year-old memory corruption bug was discovered in
rippled, the official C++ node server for the XRP Ledger. - The vulnerability stemmed from an integer overflow during type conversion (unsigned to signed int) of the
hopsfield in P2PEndpointmessages, leading to an out-of-bounds (OOB) write. - This OOB write was initially exploited for Denial of Service (DoS) by causing a deadlock in
boost::asio::io_service, makingrippledservers hang for 10 minutes before restarting. - The DoS primitive was escalated to Remote Code Execution (RCE) through virtual function table (VFT) hijacking combined with a sophisticated heap spraying technique using
TMManifestmessages. - The exploit could compromise a single node in 12 minutes (1GB traffic) or the entire XRP Ledger network from one machine in 9 days, enabling scenarios like fund theft, double-spending, or altering transaction verification logic.
- The research highlights the critical importance of memory safety in core blockchain infrastructure and rigorous security auditing of P2P protocols in decentralized systems.
About the Speaker(s)
Haoyu Yang is a Security Researcher at Tencent Security Xuanwu Lab. He specializes in blockchain and application security, bringing a strong background as a former CTF (Capture The Flag) player. His work, as demonstrated in this talk, focuses on uncovering deep-seated vulnerabilities in critical software components of decentralized systems.
Reviews
Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT
Solid, real vulnerability research in a high-value target. Yang found an 8-year-old signed/unsigned integer confusion in rippled's P2P layer, escalated it from DoS to RCE via VFT hijacking, and demonstrated a plausible path to full chain compromise. Not groundbreaking exploitation technique, but the target matters and the work is clearly his own.
Heather Calloway (CISO) — STRONG ACCEPT
A genuine chain-level vulnerability in XRP's core infrastructure — 8 years old, remotely exploitable to RCE, capable of full network takeover. If your organization holds XRP, runs nodes, or has exposure through custodians or exchanges, this is material risk disclosure. The research is solid; the implications are strategic.