井底望天:大家知道上次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亿美元下来,呵呵
也不行啊,没有其他的保护手法
关键是区块链的码农,不少是是网络码农转过来的
不是安全系统码农