专栏首页FreeBufParity多重签名合约Delegatecall漏洞回顾

Parity多重签名合约Delegatecall漏洞回顾

一、事件始末

2017年7月19日,Parity Multisig 电子钱包合约被爆出漏洞,攻击者从三个高安全的多重签名合约中窃取到超过15万以太坊(约3000万美元)。

二、漏洞原理

delegatecall的含义:<address>.delegatecall(...) returns (bool):issue low-level DELEGATECALL, returns false on failure, forwards all available gas, adjustable。 call与delegatecall的功能类似,区别仅在于后者仅使用给定地址的代码,其它信息则使用当前合约(如存储,余额等等)。注意delegatecall是危险函数,他可以完全操作当前合约的状态。

黑客通过 delegatecall 调用 initWallet 函数, initWallet 没有检查以防止攻击者在合同初始化后调用到 initMultiowned ,漏洞使得黑客能通过 library 库函数,让自己成为多个 Parity 钱包的新主人,然后调用转账函数把钱转走。

三、具体分析

1、 initWallet 函数可以改变合约的 owner

// line 216
// constructor - just pass on the owner array to the multiowned and  // the limit to daylimit
function initWallet(address[] _owners, uint _required, uint _daylimit) {
  initDaylimit(_daylimit);
  initMultiowned(_owners, _required);
}

2、 代码里使用了 delegatecall() 函数,导致所有 public 函数对所有人可见。包括 initWallet 函数。而且 initWallet 函数也没有作任何防护措施。

// line 424
function() payable {
  // just being sent some cash?
  if (msg.value > 0)
    Deposit(msg.sender, msg.value);
  else if (msg.data.length > 0)
    _walletLibrary.delegatecall(msg.data);
}

3、 攻击者先获取owner权限,将调用函数的指令放在Data中。

行为地址:https://etherscan.io/tx/0x9dbf0326a03a2a3719c27be4fa69aacc9857fd231a8d9dcaede4bb083def75ec

Function: initWallet(address[] _owners, uint256 _required, uint256 _daylimit) ***

MethodID: 0xe46dcfeb
[0]:  0000000000000000000000000000000000000000000000000000000000000060
[1]:  0000000000000000000000000000000000000000000000000000000000000000
[2]:  00000000000000000000000000000000000000000000116779808c03e4140000
[3]:  0000000000000000000000000000000000000000000000000000000000000001
[4]:  000000000000000000000000b3764761e297d6f121e79c32a65829cd1ddb4d32

4、 然后执行execute获取所有 funds

行为地址:https://etherscan.io/tx/0xeef10fc5170f669b86c4cd0444882a96087221325f8bf2f55d6188633aa7be7c

Function: execute(address _to, uint256 _value, bytes _data) ***

MethodID: 0xb61d27f6
[0]:  000000000000000000000000b3764761e297d6f121e79c32a65829cd1ddb4d32
[1]:  00000000000000000000000000000000000000000000116779808c03e4140000
[2]:  0000000000000000000000000000000000000000000000000000000000000060
[3]:  0000000000000000000000000000000000000000000000000000000000000000
[4]:  0000000000000000000000000000000000000000000000000000000000000000

四、防范方法

谨慎使用 delegatecall() 函数。 明确函数可见性,默认情况下为public类型,为防止外部调用函数被内部调用应使用 external。 加强权限控制。敏感函数应设置 onlyOwner 等修饰器。

五、资料

WalletLibrary 合约地址:https://etherscan.io/address/0xa657491c1e7f16adb39b9b60e87bbb8d93988bc3#code

The Parity Wallet Hack Explained:https://blog.zeppelin.solutions/on-the-parity-wallet-multisig-hack-405a8c12e8f7

六、团队介绍

BUGX.IO是一家致力于区块链领域的安全公司。核心团队组建于2014年,我们在区块链生态安全、行业解决方案、安全建设、红蓝对抗等方面有深厚积累与过硬专业素养。

*本文作者:BUGX.IO-Tri0nes,转载请注明来自FreeBuf.COM

本文分享自微信公众号 - FreeBuf(freebuf)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-07-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 浅析AMR智能合约批量转账溢出漏洞

    日前,互联网爆出AMR合约存在高危安全风险的交易,该合约存在批量转账溢出漏洞,当合约实现批量转账功能时,容易在计算通证增加量时发生溢出漏洞,BUGX.IO安全团...

    FB客服
  • DomLink:一款自动化的域发现工具

    DomLink是一个自动化的域发现工具。用户只需向其提供一个域名,它就会帮助我们查找与之相关联的组织和电子邮件记录,并使用这些信息执行反向的WHOIS,然后你将...

    FB客服
  • 揭秘一句话木马的套路

    可变函数:通过一个变量,获取其对应的变量值,然后通过给该值增加一个括号 (),让系统认为该值是一个函数,从而当做函数来执行。

    FB客服
  • python SMTP邮件发送

    本例使用的时python2.7环境,python3的操作应该也是差不多的。 需要用到smtplib和email两个包。

    py3study
  • Python之路-day6

    所谓高阶函数,简单点说就是将一个函数作为另一个函数的传入参数,这样我们就称这个组合函数为高阶函数。 举个例子: map()函数能接收两个参数,一个为函数,一个为...

    企鹅号小编
  • Python3.6学习笔记(二)

    对于指定索引范围取值的操作,Python提供了slice方法,类似于Excel中数据透视表的切片器。

    大江小浪
  • 函数式编程:抽象与组合

    随着我在程序开发中愈加成熟,我愈加重视底层的原理 —— 这是在我还是个初学者时所被我所忽视的,但现在随着开发经验越来越丰富,这些基础的原理也具有了深厚的意义。

    苏南
  • C++调用Python

    Python作为一门流行通用的脚本语言,可以很好的和C/C++程序结合在一起。 在一个C/C++应用程序中,我们可以用一组插件来实现一些具有统一接口的功能,一般...

    chain
  • Tensorflow简述和初步上手

    AI这个概念好像突然就火起来了,年初大比分战胜李世石的AlphaGo成功的吸引了大量的关注,但其实看看你的手机上的语音助手,相机上的人脸识别,今日头条上帮你自动...

    云时之间
  • 视频转码加密 一直失败找不到原因 ,请求帮忙

    echo $str = "https://vod.api.qcloud.com/v2/index.php?fileId=".$fileid."&transcod...

    用户1226609

扫码关注云+社区

领取腾讯云代金券