以太坊安全之EVM与短地址攻击

访客4年前黑客工具616

前言

以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(ETH)提供去中心化的以太坊虚拟机(EVM)来处理点对点合约。EVM(Ethereum Virtual Machine),以太坊虚拟机的简称,是以太坊的核心之一。智能合约的创建和执行都由EVM来完成,简单来说,EVM是一个状态执行的机器,输入是solidity编译后的二进制指令和节点的状态数据,输出是节点状态的改变。

以太坊短地址攻击,最早由Golem团队于2017年4月提出,是由于底层EVM的设计缺陷导致的漏洞。ERC20代币标准定义的转账函数如下:

function transfer(address to, uint256 value) public returns (bool success)

如果传入的 to 是末端缺省的短地址,EVM 会将后面字节补足地址,而最后的 value 值不足则用 0 填充,导致实际转出的代币数值倍增。

本文从以太坊源码的角度分析EVM底层是如何处理执行智能合约字节码的,并简要分析短地址攻击的原理。

EVM源码分析

evm.go

EVM 的源码位于 go-ethereum/core/vm/目录下,在 evm.go 中定义了 EVM 结构体,并实现了 EVM.Call、EVM.CallCode、EVM.DelegateCall、EVM.StaticCall 四种 *** 来调用智能合约,EVM.Call 实现了基本的合约调用的功能,后面三种 *** 与 EVM.Call 略有区别,但最终都调用 run 函数来解析执行智能合约

EVM.Call

EVM.CallCode

EVM.DelegateCall

EVM.StaticCall

run 函数前半段是判断是否是以太坊内置预编译的特殊合约,有单独的运行方式

后半段则是对于一般的合约调用解释器 interpreter 去执行调用

interpreter.go

解释器相关代码在 interpreter.go 中,interpreter 是一个接口,目前仅有 EVMInterpreter 这一个具体实现

EVMInterpreter 的 Run *** 代码较长,其中处理执行合约字节码的主循环如下:

大部分代码主要是检查准备运行环境,执行合约字节码的核心代码主要是以下3行

interpreter 的主要工作实际上只是通过 JumpTable 查找指令,起到一个翻译解析的作用

最终的执行是通过调用 operation 对象的 execute ***

jump_table.go

operation 的定义位于 jump_table.go 中

jump_table.go 中还定义了 JumpTable 和多种不同的指令集

jump_table.go 中的代码同样只是起到解析的功能,提供了指令的查找,定义了每个指令具体的执行函数

instructions.go

instructions.go 中是所有指令的具体实现,上述三个函数的具体实现如下:

这三个函数的作用分别是从 input 加载参数入栈、获取 input 大小、复制 input 中的参数到内存

我们重点关注 opCallDataLoad 函数是如何处理 input 中的参数入栈的

opCallDataLoad 函数调用 getDataBig 函数,传入 contract.Input、stack.pop() 和 big32,将结果转为 big.Int 入栈

getDataBig 函数以 stack.pop() 栈顶元素作为起始索引,截取 input 中 big32 大小的数据,然后传入 common.RightPadBytes 处理并返回

其中涉及到的另外两个函数 math.BigMin 和 common.RightPadBytes 如下:

分析到这里,基本上已经能很明显看到问题所在了

RightPadBytes 函数会将传入的字节切片右填充至 l 位长度,而 l 是被传入的 big32,即 32 位长度

所以在短地址攻击中,调用的 transfer(address to, uint256 value) 函数,如果 to 是低位缺省的地址,由于 EVM 在处理时是固定截取 32 位长度的,所以会将 value 数值高位补的 0 算进 to 的末端,而在截取 value 时由于位数不够 32 位,则右填充 0x00 至 32 位,最终导致转账的 value 指数级增大

测试与复现

编写一个简单的合约来测试

remix部署,调用发起正常的转账

直接尝试短地址攻击,删去转账地址的后两位,会发现并不能通过,remix会直接报错

这是因为 web3.js 做了校验,web3.js 是用户与以太坊节点交互的媒介

源码复现

通过源码函数复现如下:

实际复现

至于如何完成实际场景的攻击,可以参考文末的链接 [1],利用 web3.eth.sendSignedTransaction 绕过限制

实际上,web3.js 做的校验仅限于显式传入转账地址的函数,如 web3.eth.sendTransaction 这种,像 web3.eth.sendSignedTransaction、web3.eth.sendRawTransaction 这种传入的参数是序列化后的数据的就校验不了,是可以完成短地址攻击的,感兴趣的可以自己尝试,这里就不多写了

PS:文中分析的 go-ethereum 源码版本是 commit-fdff182,源码与最新版有些出入,但最新版的也未修复这种缺陷(可能官方不认为这是缺陷?),分析思路依然可以沿用

思考

以太坊底层EVM并没有修复短地址攻击的这么一个缺陷,而是直接在里对地址做的校验,目前各种合约或多或少也做了校验,所以虽然EVM底层可以复现,但实际场景中问题应该不大,但如果是开放RPC的节点可能还是会存在这种风险

另外还有一个点,按底层EVM的这种机制,易受攻击的应该不仅仅是这个点,只是因为这个函数是ERC20代币标准,而且参数的设计恰好能导致涉及金额的短地址攻击,并且特殊的地址易构造,所以这个函数常作为短地址攻击的典型。在其他的一些非代币合约,如竞猜、游戏类的合约中,一些非转账类的事务处理函数中,如果不对类似地址这种的参数做长度校验,可能也存在类似短地址攻击的风险,也或者并不局限于地址,可能还有其他的利用方式还没挖掘出来。

参考

[1] 以太坊短地址攻击详解

https://www.anquanke.com/post/id/159453

[2] 以太坊源码解析:evm

https://www.jianshu.com/p/f319c78e9714

原文地址:https://paper.seebug.org/1296/

相关文章

河马吃什么(河马不吃肉?)

  小河马是一种身型巨大的胎生动物,和小象、犀牛不一样,小河马是一种杂食性动物,除开喂草,还会继续吃荤,但小河马吃荤的情景大家好像较少看到。但是你看看它能够塞得下一个西瓜的血盆大口和又尖又长的牙便会了...

黑客可以查到老公的微信聊天记录吗?怎么防止呢-免费接单黑客QQ

黑客可以查到老公的微信聊天记录吗?怎么防止呢-免费接单黑客QQ 今天我跟朋友分享几个圈子里才知道的赚钱项目,我算你们口中的网红了?我是做自媒体的,百万级别博主。   有人说现在合法的 来钱最快的一个...

马桶堵了如何自己快速疏通?原来马桶堵了只要一壶开水就能搞定

马桶堵了如何自己快速疏通?原来马桶堵了只要一壶开水就能搞定

因为当初嫁老公时,家里没有准备婚房,也就三代人一起住,我家奶奶也是苦过的人,勤俭节约也成为一种习惯,以前老房子虽然是一幢的,但设计不合理,三层半才两个卫生间,还都只在一楼和二楼,奶奶住二楼,因为装的都...

辽宁新增4例本土劳动竞赛报道新冠肺炎确诊病例

  中新网1月1日电 据辽宁省卫健委网站消息,12月31日0时至24时,辽宁省新增4例本土新冠肺炎确诊病例,均属普通型病例,其中沈阳市报告2例、大连市报告2例(1例为无症状感染者转归病例);新增3例本...

黑客要获得的最高权限是什么权限(黑客如何入侵网站拿权限)

黑客要获得的最高权限是什么权限(黑客如何入侵网站拿权限)

本文目录一览: 1、Root是什么意思?获取Root权限有什么作用? 2、什么是root权限? 3、什么叫root权限 Root是什么意思?获取Root权限有什么作用? 1,root权限,系...

郭盛华个人信息(郭盛华简介 个人资料)

郭盛华个人信息(郭盛华简介 个人资料)

本文目录一览: 1、中国第一骇客是谁? 2、曾经的世界十大黑客,他们现在怎么样了? 3、深圳市前海会种科技有限公司怎么样? 4、哪国黑客的最强? 5、黑客是不是很牛逼? 6、世界十...