作者: Peter Lai
原文地址:
https://medium.com/taipei-ethereum-meetup/parity-%E9%8C%A2%E5%8C%85%E5%90%88%E7%B4%84%E6%BC%8F%E6%B4%9E-43ed412ebcd2
还记得今年7
月Parity
钱包合约被找到漏洞,结果黑客偷走了将近150,000
个以太币,会发生是因为智能合约的callback
里使用了delegatecall(msg.data)
,这个函数会呼叫data
中的函数并将msg.sender
设为原呼叫函数的地址,黑客利用这一点呼叫了initWallet
,这时你们可能会以为Parity
应该有在initWallet设置条件阻挡黑客就不能呼叫,结果竟然是没有!所以黑客就成功并改变合约的拥有者,最后再把以太币转走,细节的部分可以看这篇文章。
Parity
也在几天后修复了这个问题,修复的方式就是在init*
函数加上only_uninitialized modifier
判断,当m_numOwners > 0
时这个函数就不能使用,这时应该会想说不会再有漏洞了吧,毕竟智能合约能操作以太币,谁知道……
就在前几天有人发布了新issue
说他不小心删除了钱包的合约,因为只有合约的拥有者可以删除,那么他到底怎么删除合约?可以看到钱包合约被删除前共有两笔交易,第一笔交易呼叫initWallet
并将合约的拥有者设为自己。
function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized {
initDaylimit(_daylimit);
initMultiowned(_owners, _required);
}
交易结果:
Function: initWallet(address[] _owners, uint256 _required, uint256 _daylimit)
MethodID: 0xe46dcfeb
0:0000000000000000000000000000000000000000000000000000000000000060
1:0000000000000000000000000000000000000000000000000000000000000000
2:0000000000000000000000000000000000000000000000000000000000000000
3:0000000000000000000000000000000000000000000000000000000000000001
4:000000000000000000000000ae7168deb525862f4fee37d987a971b385b96952
第二笔交易呼叫了kill
函数,而kill
函数呼叫了suicide
(selfdestruct函数的别称,功能是将合约程序从内存块链移除,并将合约剩馀的以太币转给参数的位置),钱包的程序就从内存块链上移除了。
function kill(address _to) onlymanyowners(sha3(msg.data)) external {
suicide(_to);
}
交易結果:
Function: kill(address _to)
MethodID: 0xcbf0b0c0
0:000000000000000000000000ae7168deb525862f4fee37d987a971b385b96952
因为很多使用这个钱包的合约引入位置都写死导致很多合约不能运作,在Polkadot里第451行就将钱包合约地址写死:
address constant _walletLibrary = 0x863df6bfa4469f3ead0be8f9f2aae51c91a907b4;
因为所有逻辑判断都在钱包合约中,所以其他相依于钱包合约的现在以太币都被冻结,且看起来像这样(无法提款):
contract Wallet {
function () payable {
Deposit(...)
}
}
Parity
官方还在了解可行的解决方案,如果想查询自己有没有被影响可以到这个网站。
如何预防
这次的事件Parity
说明有两种预防方式。一种是智能合约不该有自杀的函数,这样即便黑客获得了权限也无法把合约移除。一种是有新的建议及改善时,要及时更新在线的合约或是找寻在线合约可能的漏洞,因为在这问题发生前,就有网友提议在合约部属时要自动呼叫initWallet
(pr)加强合约的安全。
如何取得冻结的资金
目前没有其他方式可以取得冻结的资金,只能期待未来有相关的改善建议实作在以太坊,或是以太坊实行硬分叉回复状态到钱包合约删除之前。
技术交流
- 区块链技术交流QQ群:
348924182
- 进微信群请加微信:
liyc1215
- 「区块链部落」公众号