区块链 智能合约安全 重入攻击(re-entrancy attack)DAO incident
Posted 软件工程小施同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链 智能合约安全 重入攻击(re-entrancy attack)DAO incident相关的知识,希望对你有一定的参考价值。
泄露资金的合约
合约有多种导致资金泄露的方式。例如,合约可能将资金转给非指定的收款人;或者将超额资金转给合法收款人等。
以下展示了对DAO合约的攻击,该攻击者借此盗取了6000万美元。大家可以观察到,该合约有一个状态变量shares。将状态变量视为可由任何函数访问的全局变量。
- shares维护用户地址和相应份额之间的映射。
- 股东可以调用withdraw()来提取他们的份额。
contract UnsafeContract1{
// Mapping of address and share
mapping(address => uint) shares;
// Withdraw a share
function withdraw() public {
if (msg.sender.call.value(shares[msg.sender])())
shares[msg.sender] = 0;
}
}
如果用户在链外调用withdraw(),那么UnsafeContract1将以良性方式运行。
在这种情况下,合约发送一条消息将份额通过msg.sender.call.value()转给用户,然后通过更新下一行中的shares将份额设置为0。
攻击发生的情况是,收款人是一个合约而非用户。当合约调用方调用withdraw()时,被调用者执行msg.sender.call.value()并将执行控制权传递给调用者即合约,在这种情况下可以回调到withdraw()。
请注意,在withdraw()中,只有在if(msg.sender.call.value())终止后,调用方的shares才会更新为0。当恶意合约回调withdraw()时,它实际上是通过强制它停留在if()指令,来防止程序指针更新shares。这允许恶意合约多次提款,直到其燃料费被消耗殆尽。
如果收款人是用户而非合约,那么他将无法回调合约,因此执行将按预期结束。
这种攻击也被称为重入攻击(re-entrancy attack)。
作者:Zilliqa爱好者中文社区
链接:https://www.jianshu.com/p/5379e44280f5
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以上是关于区块链 智能合约安全 重入攻击(re-entrancy attack)DAO incident的主要内容,如果未能解决你的问题,请参考以下文章