首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

团队前期安全研究成果

我们团队长期致力于网络安全技术研究,在区块链安全方面尤其是在底层实现方面的安全研究有深入的研究。近期,我们将会陆续公布前期研究成果,欢迎大家指正。以下为正文:

以太坊底层虚拟机实现漏洞(已修补)

ct

这是以太坊从未披露过的漏洞,以太坊底层虚拟机代码关于栈检查的代码漏洞,在官方的go语言1.5.8版本中,存在34个此类型的代码漏洞,此类型漏洞至少可以造成交易执行和虚拟机的拒绝服务攻击(DoS)。从1.6.0版本后,此类型漏洞被修复。

以太坊为了支持智能合约,设计了一个基于栈的虚拟机,EVM。智能合约被编译成为了EVM字节码。因此,一个智能合约可以被看做EVM操作的序列。EVM实现过程中,为了确保栈操作不发生错误,调用了一个检查函数,在EVM操作执行前检查栈元素数量是否支持该操作,如果不能够支持,则拒绝执行该操作。遗憾的是,检查函数的实验中出现了漏洞。简单来讲,检查函数对于EVM操作会增加和减少的栈元素数量设置不正确,而正确的设置在以太坊黄皮书上有记载(即不是设计上的错误)。

下面看看漏洞代码(来自go-ethereum 1.5.8)。

在/core/vm/vm.go的第82行开始是Run函数,该函数是用来执行EVM字节码的。下面是Run函数的部分代码。

而validateStack就是上文说的检查函数。这个检查函数并不是一个统一的函数,而是EVM为每一个EVM操作定义了一个检查函数,虽然最终还是调用到了同一个检查函数里面。定义在/vm/core/jumptable.go中。下图是前3个EVM操作的定义。

可以看到,所有EVM操作的validateStack函数都将调用makeStackFunc函数,该函数接受两个参数,定义在/vm/core/stack_table.go中,如下图。

所以,第一个参数是EVM操作需要消耗的栈元素数量,而第二参数是EVM操作产生的栈元素数量。那么,makeStackFunc实际上首先检查了栈上是否有足够的元素提供给EVM操作,然后确保操作后栈上的元素数量不会超过一个上限,StackLimit。

Unfortunately, EVM一共定了100多种操作,在1.5.8版本时,有34个操作的makeStackFunc的参数设置错误,导致makeStackFunc对栈的检查结论无效。这34个操作是BALANCE,CALLDATACOPY,所有16个SWAP和所有16个DUP。下面就给出其中4个为例。

BALANCE设置的参数是和1,但正确的设置应该是1和1。攻击者可以构造一个空的栈,然后执行BALANCE操作,validateStack检查会通过,因为第一个参数是,但执行过程中会对空栈执行pop,从而导致EVM崩溃。

CALLDATACOPY设置的参数是3和1,但正确的设置应该是3和。这个错误的设置会带来什么危害尚未分析。

16个SWAP和16个DUP设置错的非常离谱,让人感觉写这段代码的人没有很好的理解这32个操作的语义。下面给出一个SWAP的定义,其他的类似。

SWAP16表示把栈上第1个元素和第17个元素交换,所以两个参数应该设置为17和17。虽然SWAP16执行完后并不会改变栈元素的数量,但第一个参数必须设置为17,因为它要访问栈第17个元素,所以第二个参数也必须设置为17,这是makeStackFunc的实现决定的。

DUP16的问题也是一样的,正确的设置是16和17。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180114G0M1MG00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券