请选择 进入手机版 | 继续访问电脑版

Hi,Tokens

 找回密码
 立即注册
查看: 452|回复: 0

井底望天谈Parity钱包被盗事件

[复制链接]

724

主题

1091

帖子

4057

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4057
发表于 2018-4-21 11:31:11 | 显示全部楼层 |阅读模式
井底望天: 大家知道上次parity那个钱包被盗了3000万美元,是啥回事吗?
井底望天: @蝙蝠猫 懂不懂multi-sign呢?
井底望天: 多重签名
井底望天: 单签名钱包,就是你有一个私人钥匙
井底望天: 多签名钱包,就是应对你公司账号,要几个人一起签名才行
井底望天: 这个明白吗?
井底望天: 好了,现在我一个多签名钱包,好比说,我有三个钱包主人,每个人有不同的私钥
井底望天: 那么需要至少两个私钥签名才行
井底望天: 才可以动用里面的钱
井底望天: 好了,那现在搞初始化
井底望天: 我们创建一个多签名钱包,然后把我们仨个人的地址放进去,规定2/3的签名才有效
井底望天: 但是,后来发觉这个初始化加人的功能,被错误地写成了一个公开public的function
井底望天: 什么意思呢?就是任何外人,都可以调用这个功能,去添加地址
井底望天: 现在黑客来了,自己加了4个新地址进去了
井底望天: 那么就变成如果你有7个主人,4/7的签名就有效了
井底望天: 所以黑客就签了4个签名,把里面的以太币给发走了
井底望天: 就这么简单,呵呵
井底望天: 我们这里有没有专业软件高手?
井底望天: 如果有,我可以说得更具体,呵呵
井底望天: 这么说吧,因为你在以太坊上面部署合约
井底望天: 用的时候,会调用里面的程序,肯定就要交gas
井底望天: 那么节省的一个办法,就是去调用已经部署的公共库
井底望天: Parity的多签名钱包,也是这样干的,去调用了一个公共库
井底望天:
程序代码: [url=][选择][/url]
addressconstant_walletLibrary=0xa657491c1e7f16adb39b9b60e87bbb8d93988bc3;
井底望天: 那么调用方法,就是用delegatecall
井底望天: 不懂程序的,就这么说,你反正传一个名字过去,它就会调用同名的程式
井底望天: 一个例子
井底望天:
程序代码: [url=][选择][/url]
function isOwner() constant returns(bool){
  return_walletLibrary.delegatecall(msg.data);
}
井底望天: 这个就是去调用库里面的isOwner
井底望天: 但是Solidity干了一个错误的事情,就是让你可以自己设计一个后备程式
井底望天: 就是任何找不到同名的程式,都来这里
井底望天: 结果Parity的同学们就写了一个程式,让你找不到名字的送以太币的程式,全部去一个自己设定的程式
井底望天:
程序代码: [url=][选择][/url]
function() payable {
  //justbeingsentsomecash?
  if(msg.value>0)
    Deposit(msg.sender,msg.value);
  elseif(msg.data.length>0)
    _walletLibrary.delegatecall(msg.data);
}
井底望天: 这个,就是被人攻击了
井底望天: 这个程序是什么意思?
井底望天: 1.首先,你去调用一个程式,它的名字,在你的合约里面没有,就进这个地方了
井底望天: 2.如果你这个程式,里面发送以太币,就走第一个分叉,如果没有
井底望天: 3.如果没有以太币发送,但是有数据,就去第二个分叉,去调用公共库
井底望天:那么黑客就写了这么一个程式
井底望天:
程序代码: [url=][选择][/url]
functioninitWallet(address[]_owners,uint_required,uint_daylimit)
{
  initDaylimit(_daylimit);
  initMultiowned(_owners,_required);
}

井底望天: 结果这个initWallet,没有在多签名合约里面,但是在公共库里面
井底望天: 里面就调用了initMultiowned这个程式
井底望天:
程序代码: [url=][选择][/url]
functioninitMultiowned(address[]_owners,uint_required
{
  m_numOwners=_owners.length+1;
  m_owners[1]=uint(msg.sender);
  m_ownerIndex[uint(msg.sender)]=1;
  for(uinti=0;i<_owners.length;++i
  {
      m_owners[2+i]=uint(_owners);
      m_ownerIndex[uint(_owners)]=2+i;
  }
  m_required=_required;
}
井底望天: 发生了什么?
井底望天: 就是现有钱包的主人,就被全部替换掉了,呵呵
井底望天: 大家明白点了吧?
井底望天: 问题在哪里?
井底望天: 1.库里面的initWallet和initMuitiWallet,应该标上intenal,就是作为私人程式,不能允许外面调用
井底望天: internal
井底望天: 2.你应该至少检查一下,人家这个钱包是不是已经有了啊
井底望天: 如果有了,就拒绝初始化,新钱包才可以做
井底望天: 这个是Solidity这边的问题
井底望天: 那么在Parity这边,你不应该盲目让delegatecall干所有事情
井底望天: 你应该有个白名单限制哪些功能可以做
井底望天: 结果就是这次的黑客水平也不算高
井底望天: 他们只是直接找到最有钱的三个账号,去手动攻击了
井底望天: 结果白帽子们,才可以用脚本,把其他账号,给先攻击掉
井底望天: 如果黑客水平高一点
井底望天: 直接用脚本攻击,呵呵
井底望天: 那就不是这三家了额,呵呵
井底望天: 最后搞掉3100万美元,呵呵
井底望天: 白帽子好像最后救了1.8亿美元下来,呵呵
井底望天: 也不行啊,没有其他的保护手法
井底望天: 关键是区块链的码农,不少是是网络码农转过来的
井底望天: 不是安全系统码农
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Hi,Tokens  |网站地图

GMT+8, 2019-12-14 05:32 , Processed in 0.054048 second(s), 4 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表