前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >以太坊智能合约编码安全之Call注入

以太坊智能合约编码安全之Call注入

作者头像
C4rpeDime
发布2018-09-28 10:55:22
1.2K0
发布2018-09-28 10:55:22
举报
文章被收录于专栏:黑白安全黑白安全黑白安全

前言

Solidity作为一种用于编写以太坊智能合约的图灵完备的语言,除了常见语言特性以外,还提供了调用/继承其他合约的功能。在call、delegatecall、callcode三个函数来实现合约之间相互调用及交互。正是因为这些灵活各种调用,也导致了这些函数被合约开发者“滥用”,甚至“肆无忌惮”提供任意调用“功能”,导致了各种安全漏洞及风险。

以太坊智能合约编码安全之Call注入
以太坊智能合约编码安全之Call注入

上述代码就是一个典型的存在call注入问题直接导致重入漏洞的demo。

2016年7月,The DAO被攻击者使用重入漏洞取走了所有代币,损失超过60亿,直接导致了eth的硬分叉,影响深远。

2017年7月20日,Parity Multisig电子钱包版本1.5+的漏洞被发现,使得攻击者从三个高安全的多重签名合约中窃取到超过15万ETH ,其事件原因是由于未做限制的 delegatecall 函数调用了合约初始化函数导致合约拥有者被修改。

2018年6月16日,有人在先知大会上提到了一种新的攻击场景——call注�9�2,主要介绍了利用对call调用处理不当,配合一定的应用场景的一种攻击手段。

接着于 2018年6月20日,ATN代币团队发布《ATN抵御黑客攻击的报告》,报告指出黑客利用call注入攻击漏洞修改合约拥有者,然后给自己发行代币,从而造成 ATN 代币增发。

Solidity 的三种调用函数

在Solidity中,call函数簇可以实现跨合约的函数调用功能,其中包括call、delegatecall和callcode三种方式。

以下是Solidity中call函数簇的调用模型:

这些函数提供了灵活的方式与合约进行交互,并且可以接受任何长度、任何类型的参数,其传入的参数会被填充至32字节最后拼接为一个字符串序列,由EVM解析执行。

在函数调用的过程中,Solidity中的内置变量msg会随着调用的发起而改变,msg保存了调用方的信息包括:调用发起的地址,交易金额,被调用函数字符序列等。

三种调用方式的异同点

call: 最常用的调用方式,调用后内置变量msg的值会修改为调用者,执行环境为被调用者的运行环境(合约的 storage)。

delegatecall: 调用后内置变量msg的值不会修改为调用者,但执行环境为调用者的运行环境。

callcode: 调用后内置变量msg的值会修改为调用者,但执行环境为调用者的运行环境。

delegatecall滥用问题

原理

在智能合约的开发过程中,合约的相互调用是经常发生的。开发者为了实现某些功能会调用另一个合约的函数。比如下面的例子,调用一个合约A的test函数,这是一个正常安全的调用。

以太坊智能合约编码安全之Call注入
以太坊智能合约编码安全之Call注入

但是在实际开发过程中,开发者为了兼顾代码的灵活性,往往会有下面这种写法:

这将引起任意 public 函数调用的问题:合约中的delegatecall的调用地址和调用的字符序列都由用户传入,那么完全可以调用任意地址的函数。

除此之外,由于delegatecall的执行环境为调用者环境,当调用者和被调用者有相同变量时,如果被调用的函数对变量值进行修改,那么修改的是调用者中的变量。

call 安全问题

call: 最常用的调用方式,调用后内置变量msg的值会修改为调用者,执行环境为被调用者的运行环境。

call注入是一种新的攻击场景,原因是对call调用处理不当,配合一定的应用场景的一种攻击手段。

call 注入原理

call 调用修改 msg.sender 值

通常情况下合约通过call来执行来相互调用执行,由于call在相互调用过程中内置变量msg会随着调用方的改变而改变,这就成为了一个安全隐患,在特定的应用场景下将引发安全问题。

外部用户通过call函数再调用合约函数:

以太坊智能合约编码安全之Call注入
以太坊智能合约编码安全之Call注入

高度自由的 call 调用

在某些应用场景下,调用函数可以由用户指定;下面是call函数的调用方式:

从上面可以看出,call函数拥有极大的自由度:

1.对于一个指定合约地址的call调用,可以调用该合约下的任意函数

2.如果call调用的合约地址由用户指定,那么可以调用任意合约的任意函数

为了便于理解,可以将智能合约中的call函数类比为其他语言中的eval函数,call函数相当于给用户提供了随意调用合约函数的入口,如果合约中有函数以msg.sender作为关键变量,那么就会引发安全问题。

call 函数簇调用自动忽略多余参数

call函数簇在调用函数的过程中,会自动忽略多余的参数,这又额外增加了call函数簇调用的自由度。下面的例子演示call自动忽略多余参数:

以太坊智能合约编码安全之Call注入
以太坊智能合约编码安全之Call注入

例子中test函数仅接收一个uint256的参数,但在callFunc中传入了三个参数,由于call自动忽略多余参数,所以成功调用了test函数。

callcode 安全问题

由于callcode同时包含了call和delegatecall 的特性,通过上文对call和delegatecall的安全问题进行了分析和举例,可以得出的结论是call和delegatecall存在的安全问题将同时存在于callcode中,这里不再进行详细的分析。

总结

针对文中所提到的安全隐患,建议:

1.call、callcode、delegatecall调用的自由度极大,并且call会发生msg值的改变,需要谨慎的使用这些底层的函数;同时在使用时,需要对调用的合约地址、可调用的函数做严格的限制。

2.call与callcode调用会改变msg的值,会修改msg.sender为调用者合约的地址,所以在合约中不能轻易将合约本身的地址作为可信地址。

3.delegatecall与callcode会拷贝目标代码到自己的环境中执行,所以调用的函数应该做严格的限制,避开调用任意函数的隐患。

4.智能合约在部署前必须通过严格的审计和测试。

本文内容由 曲速未来 (WarpFuture.com) 安全咨询公司编译,转载请注明。 曲速未来提供包括主链安全、交易所安全、交易所钱包安全、DAPP开发安全、智能合约开发安全等相关区块链安全咨询服务

添加收藏

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 原理
  • 总结
相关产品与服务
安全咨询
安全咨询(Cybersecurity Consultation Service,CSCS)依据国家政策和国家信息安全标准,基于客户信息安全需求,提供企业信息安全规划与管理方面的安全咨询。安全咨询协助企业识别信息资产及业务流程的信息安全弱点,并针对信息安全威胁提供信息安全风险处理规划建议。安全咨询包括合规类咨询服务、安全管理咨询服务、安全体系咨询服务与行业安全解决方案咨询服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档