主页 > imtoken钱包官方网站 > 以太坊安全 EVM 和短地址攻击
以太坊安全 EVM 和短地址攻击
时间:2020-08-18
●前言●
以太坊(Ethereum)是一个具有智能合约功能的开源公共区块链平台,通过其专用的加密货币以太币(ETH)提供去中心化的以太坊虚拟机(EVM)来处理点对点合约。 EVM(Ethereum Virtual Machine),以太坊虚拟机的简称,是以太坊的核心之一。 智能合约的创建和执行由 EVM 完成。 简单地说,EVM 是一个状态执行机。 输入是solidity编译的二进制指令和节点的状态数据,输出是节点状态的变化。
以太坊短地址攻击,由Golem团队于2017年4月首次提出以太坊虚拟机处理的事务包含,是底层EVM设计缺陷导致的漏洞。 ERC20代币标准定义的传递函数如下:
如果传入默认末尾的短地址,EVM 会用后面的字节填充该地址,如果最后一个值不足,则用 0 填充,导致转出的代币实际价值翻倍。
本文从以太坊源码的角度分析了EVM底层是如何处理和执行智能合约字节码的,并简要分析了短地址攻击的原理。
●EVM源码分析●
evm.go
EVM源码位于该目录下,其中定义了EVM结构,实现了调用智能合约的四个方法,实现了合约调用的基本功能。 后三种方式与调用函数解析执行智能合约略有不同
EVM。 称呼
EVM。 调用代码
EVM。 代表电话
EVM.静态调用
函数前半部分是判断是否是以太坊内置的特殊预编译合约,有单独的运行模式
后半部分为通用合约调用解释器执行调用
解释器.go
解释器相关的代码是一个接口,目前只有一个具体实现
合同来自于
方法代码比较长,处理执行合约字节码的主循环如下:
大部分代码主要是检查准备运行的环境,执行合约字节码的核心代码主要是以下3行
主要工作其实就是查说明书,起到翻译分析的作用
最后的执行是调用对象的一个方法。
跳转表.go
定义于
也定义在和各种不同的指令集中
基本指令集中有3条处理指令,分别是
中的代码也只是解析功能,提供命令搜索,定义了每条命令的具体执行函数
说明.go
是所有指令的具体实现,上面三个函数的具体实现如下:
这三个函数的作用分别是从加载参数入栈,获取大小,将参数拷贝到内存。
我们重点关注函数如何处理栈中的参数
函数调用函数,传入,和,将结果入栈
函数以栈顶元素为起始索引,截取中等大小的数据,传入处理并返回
涉及的另外两个函数如下:
分析到这里,基本上就可以看清问题了。
函数会将传入的byte slice右填充到位长,但是传入的是32位长度
因此,在短地址攻击中,如果被调用的函数是低位默认地址,由于EVM在处理过程中总是拦截32位长度,所以会在该值的高位值末尾加0,并且截取时由于位数小于32位,会右补到32位,最终导致转账呈指数级增长
●测试与复现●
写一个简单的合约来测试
Remix 部署,调用发起正常传输
为了
直接尝试短地址攻击,删除转账地址最后两位,会发现过不了,remix会直接报错
这是因为验证,它是用户与以太坊节点交互的媒介
源代码复现
通过源码功能复现如下:
实际再现
至于如何在实际场景中完成攻击,可以参考文末链接[1],使用绕过限制
实际上,验证仅限于显式传入转账地址的函数。 比如传入的参数是序列化数据,无法验证,就可以完成短地址攻击。 有兴趣的可以自己试试,这里就不多写了
PS:文中分析的源码版本是源码和最新版本有些不同,但是最新版本并没有修复这个缺陷(可能官方不认为这是缺陷?),分析思路还能用
●思考●
以太坊底层EVM并没有修复这种短地址攻击的缺陷,而是直接检查其中的地址。 目前各种合约或多或少都有检查以太坊虚拟机处理的事务包含,所以虽然底层EVM可以复现,但在实际场景中,问题应该不大,但如果是开放的RPC节点,还是有可能存在这样的风险。
还有一点。 根据底层EVM的机制,易受攻击的不仅仅是这一点,因为这个函数是一个ERC20代币标准,参数的设计恰好可以导致涉及金额的短地址攻击, 并且特殊地址易于构造,因此该函数常被用作典型的短地址攻击。 在其他一些非代币合约中,比如竞猜、游戏合约,以及一些非转账交易处理函数中,如果不对地址等参数进行长度校验,也可能存在类似短地址攻击的风险,或者不进行仅限于地址,可能还有其他尚未发现的利用方法。
参考
[1] 以太坊短地址攻击详解
[2] 以太坊源码分析:evm
过去的流行
【Seebug红利】ZoomEye 2020发布最新版本升级,顺便送你高级会员!
从代码的角度看各种子域名收集工具
Shiro-550 PoC写作日记
我觉得点“在看”就好了。