研究尝试重入攻击 / 学习智能合约#59

这段时间听到很多黑客攻击事件,不免让人惴惴不安。虽然大多发生在一些新的项目,但金额都挺大,而且一般都是审计过的知名项目。所以,还是安全为上,自己多看多想,自己做判断,一些风险大的项目就不要参与了,特别是跨链桥!

重翻了下以太坊的安全问题,里面着重强调了重入攻击。以前也曾了解些,没有深入,现在刚好趁着空闲,来尝试下重入攻击。

重入攻击最早最知名的是DAO这个项目,事件发生后导致了ETC的分叉,后果还是很严重的。我查了下代码 ,想重现下,其实真是我想多了,漏洞早就修补好了!

发生场景

重入攻击发生在以太坊转帐的时候,msg.sender.call.value(_amount)();这条代码有重入风险。以太坊有两种帐户类型:一是外部帐户(用户地址),另一个是合约帐户 。如果是外部帐户,代码可以正常执行。但如果是合约的话,这条代码就有问题了。msg.sender.call.value(_amount)();会触发这个合约的fallback函数!如果fallback函数有恶意代码,那乐子就大啰!比如这样:

fallback() payable external {
   ibank.withdraw();
}

这就相当于重复不停地取以太坊了!

复现了一下代码,这些代码早就不能用啰,是我想多了!如下所示:
call.jpg

msg.sender.call.value(_amount)(); //重入代码,早已修补!

找了下新的写法,msg.sender.call{value: 1 ether}(""); 新写法 ,其实也是没有重入风险了。当然现在一般不用这么底层的写法了,推荐使用transfer, 是这样的payable(msg.sender).transfer(1 ether);transfer有2300gas的限制,所以不可能有重入风险了。