Solidity安全之delegatecall 的滥用问题

曲速未来安全区
曲速未来安全区 机构得得号

Aug 10, 2018 专注于为读者提供区块链安全领域最新讯息

摘要: Soildity 作为编写智能合约的语言,已经被广泛的应用。但同时,开发者和用户也得到了惨痛的教训,智能合约的安全问题层出不穷。因此,我们总结了一些常见的Solidity安全问题。前车之鉴,后车之师,希望后来者能有所警惕。

Soildity 作为编写智能合约的语言,已经被广泛的应用。但同时,开发者和用户也得到了惨痛的教训,智能合约的安全问题层出不穷。因此,我们总结了一些常见的Solidity安全问题。前车之鉴,后车之师,希望后来者能有所警惕。
delegatecall 「滥用」问题

在 Solidity 中提供了delegatecall函数来实现合约之间相互调用及交互。各种调用,导致了delegatecall函数被合约开发者“滥用”,甚至“肆无忌惮”提供任意调用“功能”,导致了各种安全漏洞及风险。

Delegatecall是一种常用的调用函数,它的特点是调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。

代码分析

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

 

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

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

相关事件

7 月 19 日,Parity发布安全警报,警告其钱包软件1. 5 版本及之后的版本存在一个漏洞。据该公司的报告,确认有153,000ETH(大约价值 3000 万美元)被盗。

因为initWallet函数是公开函数( public function) , 攻击者调用initWallet,重新初始化钱包会把之前合约钱包所有者覆盖, 即可改变钱包所有者。 

漏洞代码:

攻击过程技术分析还原:

第一步:成为合约的owner

通过往这个合约地址转账一个value = 0 ,msg.data.length > 0 的交易, 执行到_walletLibrary.delegatecall的分支,该函数能无条件的调用合约内的任何一个函数,黑客调用了一个叫做 initWallet的函数:

这个函数再次调用initMultiowned函数:

不幸的是,initWallet没有检查以防止攻击者在合同初始化后调用到initMultiowned, 这个函数使得这个合约的所有者被改为攻击者,相当于从unix中获得了root权限。

第二步: 转账, 剩下的事情就很清晰了,通过调用execute函数转账到黑客的地址:

第一个参数: address to= 0xb3764761e297d6f121e79c32a65829cd1ddb4d32, 转账额度116779808c03e4140000是为以Wei为单位的的eth,即 82189000000000000000000,可以通过如下的代码获得具体数值。

作为已经有过被利用先例的漏洞,开发者在智能合约在部署前必须通过严格的审计和测试,在编写时使用delegatecall要更加小心。

链得得仅提供相关信息展示,不构成任何投资建议
本文系作者 曲速未来安全区 授权链得得发表,并经链得得编辑,转载请注明出处、作者和本文链接

更多精彩内容,关注链得得微信号(ID:ChainDD),或者下载链得得App

分享到:

相关推荐

    评论(0

    Oh! no

    您是否确认要删除该条评论吗?

    分享到微信