CVE-2018-12018:以太坊Geth拒绝服务漏洞分析复现(附EXP)

BCSEC  2111天前

前言

在Geth中节点分为轻节点(light node)和全节点(full node)两大类,目前以太坊网络中最常见的节点还是轻节点(同步速度块、省硬盘)

在同步区块数据的时候,虽然是P2P模式,但是也分客户端和服务端。很容易理解,获取数据的节点属于客户端,推送数据的属于服务端。

此漏洞主要利用的是轻节点的协议,所以我们主要研究LES(Light-Ethereum-Subprotocol)子协议,在这里可以看到LES协议发包的详细说明,我们直接来看重点,GetBlockHeaders消息:
图片.png

缺陷代码

les/handler.go文件中处理GetBlockHeaders消息的缺陷代码:


图片.png可以看到query.Skip+1被带入了GetBlockHashesFromHash函数,我们再来看看GetBlockHashesFromHash:
图片.png

此函数是用于通过某个区块hash(第一个参数)获取与这个区块相关联的区块hash,max参数(第二个)则是用来限定获取的总量,再回到之前的代码:

if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {

可以理解为获取query.Skip+1数量的区块hash,然后从中取出第query.Skip个区块hash。

当query.Skip不存在于pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)数组的下标中时,将会发生抛出如下常见异常(下标超出数组范围):

index out of range

那怎么让query.Skip不存在于如上数组的下标中呢?按照之前的逻辑,query.Skip已经被包含再数组中了。

整型溢出问题

整型溢出问题在很多语言中都存在,go也不例外,我们可以来做一个小实验,测试代码:
图片.png

我给c变量赋值为uint64变量的最大值,然后让他加一下我输入的数值,并打印结果,以下是测试结果:
图片.png

可以很明显的看到,已经产生了整型溢出,18446744073709551615+1=0,18446744073709551615+2=1。

我们再回头看Geth的代码片段:


图片.png

以上是Geth的GetBlockHeaders消息具体代码实现,可以看到Skip变量被定义为uint64类型,意味着有整型溢出的风险。

uint64类型的数值范围是0至0xffffffffffffffff,意思就是当Skip为0xffffffffffffffff时,Skip+1的结果是0,GetBlockHeaders消息是由客户端发起的,所以这些参数都是可控的,包括Skip。

当query.Skip为0xffffffffffffffff,那么将query.Skip代入pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip]的结果就是:

pm.blockchain.GetBlockHashesFromHash(header.Hash(), 0)[0xffffffffffffffff]

很明显,如上执行便会抛出index out of range异常。

问题复现

由于此问题只出现于LES服务中,所以我们的服务端节点以LES服务启动:

./geth  --datadir ./data2  --nodiscover --testnet  --lightserv 20 console


图片.png

然后使用由BCSEC团队编写的EXPhttps://github.com/bcsecorg/PoCs/tree/master/Geth_EPoD_EXP(CVE-2018-12018)来发送恶意包。
图片.png

执行结果:

图片.png

可以看到,EXP显示了attack success,Geth节点也已经抛出异常并退出了。

修复

服务端节点分为普通节点和轻节点,此问题实际上在普通节点上已经出现过,并且已经修复了,eth/handler.go代码片段:
图片.png

在les/handler.go中出现的是同样的问题,所以修复方式也基本一致:


图片.png

危害

具体影响范围是使用--lightserv方式启动并版本小于1.8.11的Geth节点,所以能直接造成影响的就只有一部分,并不能对所有版本小于1.8.11的Geth节点造成影响,据BCSEC安全团队统计,以太坊主网中版本小于1.8.11的Geth节点大约占全网节点的25%左右。

最新评论

昵称
邮箱
提交评论