By:小白
背景概述
上期我们了解了利用tx
functionmakeMoney(addressrecipient)publicpayable{require(msg
}contractVault{addressprivatemaker;addressprivateowner;uint256transferGasLimit;constructor()payable{owner=msg
modifierOnlyMaker(){require(msg
modifierOnlyOwner(){require(msg
functionsetMacker(address_maker)publicOnlyOwner{maker=_maker;}functiontransfer(addressrecipient,uint256amount)externalOnlyMaker{require(amount<=address(this)
functionwithrow()publicOnlyOwner{(boolsuccess,)=owner
receive()externalpayable{}fallback()externalpayable{}}//ThiscodeishiddeninaseparatefilecontractHack{eventtaunt(stringmessage);addressprivateevil;constructor(address_evil){evil=_evil;}modifierOnlyEvil(){require(msg
functiontransfer()publicpayable{emittaunt("Haha,youretherismine!");}functionwithrow()publicOnlyEvil{(boolsuccess,)=evil
receive()externalpayable{}fallback()externalpayable{}}
数据:熊市在30天内导致25家加密货币交易所消失:7月6日消息,截至7月6日,全球加密货币交易所数量为500家,较前几个月的高位有所下降。根据CoinMarketCap的数据,考虑到6月6日的数字为525,Finbold通过使用网络存档工具确定该行业在30天内失去了25家交易所。(Finbold)[2022/7/6 1:55:18]
局分析
可以看到,上述代码中存在三个合约,我们先结合前置知识中的A,B,C三个角色来区分三个合约分别代表什么角色:
MoneyMaker合约代表A合约;
Vault合约代表B合约;
Hack合约代表C合约。
所以用户以为的调用路径为:
MoneyMaker->Vault。
而实际的调用路径为:
MoneyMaker->Hack。
下面我们来看看攻击者如何完成局的:
Game Space宣布将兼容EIP-4907协议,推出可租赁的NFT游戏道具:7月4日消息,GameFi as a Service平台Game Space宣布将兼容EIP-4907协议,推出可租赁的NFT游戏道具。ERC-4907协议通过双角色设置,可实现NFT所有权与使用权的分离,降低Utility NFT租赁的开发和集成成本。此外,通过使用Game Space提供的SDK,游戏开发者可提高开发速度,并拥有包括一、二级交易市场在内的整套区块链功能。
Game Space提供的服务方案包括中心化版本与去中心化版本。推出可租赁的NFT游戏道具后,Game Space两个版本可同时支持二级市场租赁功能。[2022/7/4 1:49:55]
1.?Evil部署Vault(B)合约并在合约中留存100ETH资金,在链上将Vault(B)合约开源;
2.?Evil部署Hack(C)恶意合约;
3.?Evil放出消息说他将会部署一个开源的赚钱MoneyMaker(A)合约,部署时会将Vault(B)合约地址传入且会调用Vault.setMacker()将maker角色设置为MoneyMaker合约地址,任何人调用MoneyMaker.makeMoney()向合约中打入不少于一个以太都会得到双倍以太的回报;
Ripple和Stellar帮助Novatti Group推出AUDC稳定币:金色财经消息,总部位于澳大利亚的Ripple客户Novatti Group发布消息称,正在与Ripple金融科技巨头合作建立一个基于澳大利亚的稳定币AUDC,并计划在XRPLedger上发行它。在推出即时跨境支付后,Stellar和Ripple将共同帮助在其网络上推广AUDC的使用。(u.today)[2022/6/9 4:14:01]
4.?Bob收到消息,了解到MoneyMaker合约的存在,他看了MoneyMaker(A)和Vault(B)合约的代码并检查了Vault(B)合约中的余额发现逻辑确实如Evil说的那样,他在没有检查MoneyMaker(A)部署交易的情况下就相信了Evil;
5.?Bob调用MoneyMaker.makeMoney()向合约中打入自己全部身家20ETH,在他满怀期待等着收到Vault(B)打来的40ETH时等来的却是一句"Haha,youretherismine!"。
咋回事呢?其实这个局非常简单但是很常见。Evil在部署MoneyMaker合约时传入的并不是Vault合约的地址,而是传入了Hack合约的地址。所以当Bob调用MoneyMaker.makeMoney()时并不会像他想像中的那样MoneyMaker.makeMoney()去调用Vault.transfer()回打给他双倍的以太,而是调用了Hack.transfer()抛出了一个事件:"Haha,youretherismine!"。最后Evil调用Vault.withrow()将Vault合约中的100ETH转出,并通过Hack.withrow()将Bob转入的20ETH转出。
预防建议
以太坊黑暗森林中你能相信的只有自己,不要相信任何人精彩的话术,交易记录不会造假,只有自己验证了对应的那笔交易后才能相信对方说的话是对的。
注:本文参考自《SoliditybyExample》https://solidity-by-example.org/hacks/randomness
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。