EPoD: Ethereum Packet of Death (CVE-2018–12018)

PeckShield
4 min readJun 27, 2018

PeckShield has so far discovered quite a few critical smart contract vulnerabilities. Besides smart contracts, the Ethereum ecosystem also includes other various components that are equally exposed to possible exploitation. Obviously, one such component is the core of Ethereum, i.e., the underlying client software running on each Ethereum node. If she takes down an Ethereum client/node, an attacker could completely get rid of the computation power contributed by the client/node. And if many Ethereum clients/nodes are all of a sudden knocked offline, their corresponding computation power could be immediately lost, causing serious disruption to the entire Ethereum operations. In this writing, we are going to reveal a critical vulnerability identified in popular Ethereum clients, which could be exploited to cause serious impact on the whole Ethereum network.

Background

Before diving into the details of the vulnerabilities, we would like to start from an introduction to Ethereum clients. As written in Ethereum foundation website, there are three independent official implementations of Ethereum clients. Those clients have almost identical functionalities for maintaining the consensus. Among the three, Go Ethereum, a.k.a. geth, is the official implementation written in Go, which is fully open source and licensed under the GNU LGPL v3. And, it is also the most popular Ethereum client. According to Ethernodes, geth has around two-thirds share while the runner-up, Parity (a Rust implementation by Parity Technologies), has most of the remaining one-third (Figure 1).

Figure 1: Market Share of Various Ethereum Clients from Ethernodes

Also, the data from Ethstats shows similar statistics (Figure 2).

Figure 2: Different Ethereum Clients from Ethstats

Given geth is the majority in the Ethereum network, any critical vulnerability of it could possibly cause severe damages to the entire Ethereum ecosystem. Researchers at PeckShield have discovered a series of vulnerabilities that could crash or freeze any geth node. Those nasty bugs can bring down a major portion of computing power of the Ethereum network.

Details

At the core of Ethereum, all client implementations should follow the same protocol for maintaining the consensus. Those protocols include RLPx, ÐΞVp2p, and many subprotocols like Ethereum Wire Protocol or Light Ethereum Protocol.

Figure 3: Ethereum Protocol Stack

Figure 3 illustrates the protocol layers used in Ethereum. For supporting “light” clients, the Light Ethereum Subprotocol (LES) allows an Ethereum node to only download block headers as they appear and fetch other parts of the blockchain on-demand. To achieve that, we also need a full (or archive) node acting as the LES server to serve the light nodes. The following command can start a full geth node with LES support:

geth --lightserv 20

While an LES client requesting block headers from an LES server, the GetBlockHeadersmessage is sent from the client and the message handler on the server side parses the message. The following figure shows the code snippet of geth’s implementation of the GetBlockHeaders message handler:

Figure 4: GetBlockHeaders Handler in geth

Here, the LES client sends the query in following format:

// getBlockHeadersData represents a block header query.
type getBlockHeadersData struct {
Origin hashOrNumber // Block from which to retrieve headers
Amount uint64 // Maximum number of headers to retrieve
Skip uint64 // Blocks to skip between consecutive headers
Reverse bool // Query direction
}

Starting from line 17, the not reverse case is handled by the LES server. In line 19, the LES server checks if there are still block headers available after skipping query.Skip blocks. If the check is passed, GetBlockHashesFromHash() is called (line 20) and an array of block headers is returned.

However, the input data, query, is not properly validated. An attacker can craft a malicious query with query.Skip = -1 (0xFFF…F). When query.Skip+1 is passed into GetBlockHashesFromHash(), an array with maximum size=0 would be allocated. Then, by accessing to the zero size array with index query.Skip = 0xFFF…F, the LES server crashes and burned, as indicated in the following figure.

Timeline

Figure 5: CVE-2018–12018 Bug Report

This is the first part of the series, we will reveal other findings some time later.

About US

PeckShield Inc. is a leading blockchain security company with the goal of elevating the security, privacy, and usability of current blockchain ecosystem. For any business or media inquires, please contact us at Telegram, Twitter, or Email.

--

--