GarlicRust - heartbleed style vulnerability in major I2P C++ router implementations
High
Vulnerability Details
Brief
-----
I2pd and kovri are both C++ I2P routers that share the same code base, as kovri was forked from i2pd several years ago. The vulnerability lies in a common code piece, making both implementations vulnerable, as was acknowledged by orignal, the main developer of i2pd.
The vulnerability is that there is lack of sanitation checks when handling Garlic messages in the both routers: by sending a specially crafted Garlic message, an attacker can cause the router to send onward an I2P message containing leaked RAM data, triggering a massive (up to ~16KB) information leakage.
Technical Details:
===========
Code Version: Taken from Kovri Github on the 18th of November 2017
Commit 5aafe6608519d31e537c97b24ea7b23aa372dd5b
Vulnerable File: src\core\router\garlic.h
Vulnerable Function: GarlicDestination::HandleGarlicPayload
The function is responsible to parse and handle Garlic Payloads: several independent Garlic Cloves.
When handling a clove with a delivery type of "DeliveryTypeTunnel" there are insufficient checks on the message, before it is wrapped and sent onward:
```cpp
GarlicDeliveryType delivery_type = (GarlicDeliveryType)((flag >> 5) & 0x03);
switch (delivery_type) {
case eGarlicDeliveryTypeLocal:
LOG(debug) << "GarlicDestination: Garlic type local";
HandleI2NPMessage(buf, len, from);
break;
case eGarlicDeliveryTypeDestination:
LOG(debug) << "GarlicDestination: Garlic type destination";
buf += 32; // destination. check it later or for multiple destinations
HandleI2NPMessage(buf, len, from);
break;
case eGarlicDeliveryTypeTunnel: {
LOG(debug) << "GarlicDestination: Garlic type tunnel";
// gateway_hash and gateway_tunnel sequence is reverted
std::uint8_t* gateway_hash = buf;
buf += 32;
std::uint32_t gateway_tunnel = bufbe32toh(buf);
buf += 4;
std::shared_ptr<kovri::core::OutboundTunnel> tunnel;
if (from && from->GetTunnelPool())
tunnel = from->GetTunnelPool()->GetNextOutboundTunnel();
// EI [BUG-TRACE] : The payload length is based on an unchecked length field
// EI : from the just found I2NP message contained in the clove.
// EI : When creating and sending this message onward we may leak
// EI : heap memory data to the destination node [18/11/2017]
if (tunnel) { // we have send it through an outbound tunnel
auto msg = CreateI2NPMessage(buf, kovri::core::GetI2NPMessageLength(buf), from);
tunnel->SendTunnelDataMsg(gateway_hash, gateway_tunnel, msg);
} else {
LOG(debug)
<< "GarlicDestination: no outbound tunnels available for garlic clove";
}
break;
}
case eGarlicDeliveryTypeRouter:
LOG(warning) << "GarlicDestination: Garlic type router not supported";
buf += 32;
break;
default:
LOG(error)
<< "GarlicDestination: unknown garlic delivery type "
<< static_cast<int>(delivery_type);
}
buf += kovri::core::GetI2NPMessageLength(buf); // I2NP
buf += 4; // CloveID
buf += 8; // Date
buf += 3; // Certificate
// EI [BUG_TRACE] : This check is too late since the I2NP message was already sent. [18/11/2017]
if (buf - buf1 > static_cast<int>(len)) {
LOG(error) << "GarlicDestination: clove is too long";
break;
}
```
This vulnerability was first sent to the kovri bug bounty program (under the Monero project), later to be found as out-of-scope since kovri was found pre-mature and they removed it from the bug bounty scope. As part of the submission to the kovri project I demonstrated an exploit, and sent the project the entire test lab so they could re-create the exploit. Later on, orignal (i2pd) acknowledged the vulnerability in i2pd and issued a quick fix that can be found in i2pd version 2.17.0.
I am attaching the logs from the exploit demonstration to this ticket,. The logs shows the debug trace of the victim router and the leaked message as it was received by the attacker router. More info can be found in my blog post regarding the vulnerability - [link](https://eyalitkin.wordpress.com/2017/12/04/cve-publication-garlicrust-cve-2017-17066/).
After both projects patched the vulnerability, a public CVE was issued: CVE 2017-17066 a.k.a GarlicRust.
## Impact
The PoC exploit demonstration (elaborated [here](https://eyalitkin.wordpress.com/2017/12/04/cve-publication-garlicrust-cve-2017-17066/)) shows that the GarlicRust vulnerability can be exploited to leak sensitive memory data from any victim C++ i2p router. The exploit is **logical** and triggers no memory errors, and so it can be used **repeatedly** and without worries. An attacker can use this vulnerability in an attempt to read **session keys, private keys, old messages** or any other valuable assets that is stored on the target’s heap.
This vulnerability poses a **major threat to the anonymity** of the users in the Invisible Internet Protocol network (I2P). This threat also impact several crypto-currencies as the I2P network is used as an additional anonymity layer in major crypto-currencies such as: Anoncoin (ANC), and Monero (XMR).
Actions
View on HackerOneReport Stats
- Report ID: 295740
- State: Closed
- Substate: resolved
- Upvotes: 3