钓鱼这样才好玩 — 记一次有意思的钓鱼样本分析

区块链安全 2年前 (2022) admin
660 0 0

前言

熊市的投资生活总是很无聊的,不是亏就是血亏,但是在熊市里分析技术还是比较有趣的,因为这个时候黑客都会竭尽所能的用自己的方法去骗大家的钱,这个时候的案例反而是最有趣的,前两天收到同事的一个案例,初看上去像是一个授权钓鱼,仔细研究之后还发现别有一番风采,分析过后决定记录下,看看熊市钓鱼手法的最新操作 😀

技术分析

本次样本的交易哈希为 https://bscscan.com/tx/0x4d208e542cbcb0919cccb1d8209a18d8097c0b09e1ce2f600a8d041193abe670,我们把它放到 etherscan 后,可以看到以下的结果

钓鱼这样才好玩 — 记一次有意思的钓鱼样本分析

芜湖,这很明显就是一笔 approve 交易,立马联想到了 approve钓鱼,然后又立马可以下结论是授权钓鱼攻击,好了,3s 不到完成分析,结束 😀 然而真的是这样吗?仔细一看,这个交易细节里头,似乎还有东西是 Chi Token,还有我们再观察一下授权的是一个叫 DBT 的代币,查看这个代币的简介

钓鱼这样才好玩 — 记一次有意思的钓鱼样本分析

芜湖,价值全都是0,总量也只有可怜的 3000 枚代币,总结下来就是搞了一波限量发行价格还全都是0,也就是说这波授权骗了用户一波不值钱的代币,但是回看 Chi Token 这个关注点,这个代币是 1 inch 发行的一个 Gas Token,这个代币唯一的作用就是用来节省交易过程终的gas,概括来说就是这个 gas token 它利用的是原理是以太坊的状态清理机制,在清理存储插槽(storage slot)和删除带有自毁操作码的合约(这些操作都可以删减全局状态树)时,会收到 gas 退款。这些操作都可以被认为具备负 gas 价格。 – 清理/自毁合约:- 24,000 gas – 清理/删除存储:-15,000 gas

当 EVM 执行这类操作时,gas 退款是通过一个独立的交易退款计量器来计算的。gas 退款只会在交易结束时提供。另外,最高 gas 退款量是该交易所消耗 gas 量的一半。具体的原理我放在文章的末尾,大家感兴趣的可以自行研究下。

回到我们的分析,既然用上了 Chi Token ,那么这个交易大概率是和 gas 问题相关的,为了探明交易的细节,我们把交易放到 Blocksec 的分析工具上看看

钓鱼这样才好玩 — 记一次有意思的钓鱼样本分析

芜湖,通过分析交易,我们不难发现,在用户调用 approve 进行代币授权的过程中,DBT 代币在函数的内部还调用了 Chi Token  mint 函数,然后就是开始一系列的通过 create2 进行的合约创建操作。为了看明白这里发生了什么,我们看一下 Chi Token 这里的相关代码

function mint(uint256 value) public {
uint256 offset = totalMinted;
assembly {
mstore(0, 0x746d4946c0e9F43F4Dee607b0eF1fA1c3318585733ff6000526015600bf30000)

for {let i := div(value, 32)} i {i := sub(i, 1)} {
pop(create2(0, 0, 30, add(offset, 0))) pop(create2(0, 0, 30, add(offset, 1)))
pop(create2(0, 0, 30, add(offset, 2))) pop(create2(0, 0, 30, add(offset, 3)))
pop(create2(0, 0, 30, add(offset, 4))) pop(create2(0, 0, 30, add(offset, 5)))
pop(create2(0, 0, 30, add(offset, 6))) pop(create2(0, 0, 30, add(offset, 7)))
pop(create2(0, 0, 30, add(offset, 8))) pop(create2(0, 0, 30, add(offset, 9)))
pop(create2(0, 0, 30, add(offset, 10))) pop(create2(0, 0, 30, add(offset, 11)))
pop(create2(0, 0, 30, add(offset, 12))) pop(create2(0, 0, 30, add(offset, 13)))
pop(create2(0, 0, 30, add(offset, 14))) pop(create2(0, 0, 30, add(offset, 15)))
pop(create2(0, 0, 30, add(offset, 16))) pop(create2(0, 0, 30, add(offset, 17)))
pop(create2(0, 0, 30, add(offset, 18))) pop(create2(0, 0, 30, add(offset, 19)))
pop(create2(0, 0, 30, add(offset, 20))) pop(create2(0, 0, 30, add(offset, 21)))
pop(create2(0, 0, 30, add(offset, 22))) pop(create2(0, 0, 30, add(offset, 23)))
pop(create2(0, 0, 30, add(offset, 24))) pop(create2(0, 0, 30, add(offset, 25)))
pop(create2(0, 0, 30, add(offset, 26))) pop(create2(0, 0, 30, add(offset, 27)))
pop(create2(0, 0, 30, add(offset, 28))) pop(create2(0, 0, 30, add(offset, 29)))
pop(create2(0, 0, 30, add(offset, 30))) pop(create2(0, 0, 30, add(offset, 31)))
offset := add(offset, 32)
}

for {let i := and(value, 0x1F)} i {i := sub(i, 1)} {
pop(create2(0, 0, 30, offset))
offset := add(offset, 1)
}
}

_mint(msg.sender, value);
totalMinted = offset;
}

以上就是 mint 函数的相关实现,全部都是用 assembly 来实现的,这里我说一下大概的逻辑,mint 函数实际上是根据 value 参数来决定 #6 行中的循环次数,在这个循环里,会不停的通过 create2 来创建合约,然后合约创建完后会给调用该函数的用户分发 Chi Token (L32)。回顾上文说的技术细节,在以太坊中,是可以通过合约创建来消耗一定量的 gas 的。那么既然 mint 操作代表的是存储的过程,那么一定有一个对应的释放的过程,通过查看 Chi Token 合约细节,这个函数叫 free,顾名思义,就是用来释放创建合约消耗的 gas 的,我们一起来看下逻辑

 function free(uint256 value) public returns (uint256)  {
_burn(msg.sender, value);
_destroyChildren(value);
return value;
}

free 合约的操作很简单,就是根据 value 参数首先燃烧掉你的 Chi Token 代币,然后根据销毁的代币量来调用 _destoryChildren 来销毁对应在 mint 函数中创建的合约,_destoryChildren 的逻辑这里不展开,主要的功能就是销毁合约,再次回顾前面的知识点,由于以太坊的存储回收机制,在销毁合约的过程中,会返还一定量的gas给到用户,也就是说,只要你持有 Chi Token,那么你就可以不停的销毁合约来获取一定的 gas 补偿。我们再来回看最开始的钓鱼交易:

钓鱼这样才好玩 — 记一次有意思的钓鱼样本分析

很明显这里只有一个 mint 操作,没有 free 操作,说明这里 gas 只是单方面的存储了起来,并没有被释放掉,而 mint 操作是在 approve 函数里调用的,根据 mint 函数的逻辑,这里 Chi Token 分发给的是 DBT 这个合约,而不是分发给调用 approve 的用户,但是由于这笔交易是用户发起调用的,在以太坊中,交易的 gas 费用都是由交易的发起者支付的,也就是说在这个过程中所有合约创建的 gas 都是用户支付的,但是这个过程中产生的 chi token 是归 DBT 合约的,在后续过程中,攻击者就可以从 DBT 这个合约中提取 chi token 来调用 free 操作来取回用户创建合约的 gas

总结

通过上面的分析,我们不难发现,这一次的钓鱼事件,初看上去很想是一起 approve 钓鱼事件,实际上这是一个通过 approve 操作伪装成 gas stealer 的钓鱼操作,其本质是通过以太坊的存储清理机制利用 1 inch 实施的一起钓鱼攻击,这种攻击隐匿性很高,用户难以察觉,因为根本没有任何代币或者 NFT 的授权,只是损失了比较多的 gas,但 gas 本身也是链代币,也是很值钱的,所以本质上你是损失了很多的手续费。所以我们还是要警惕这种新型的钓鱼攻击,保护好自己的资产。

附录

  • Chi token 技术详解: https://learnblockchain.cn/article/1707

  • What is gas Token: https://gastoken.io/


原文始发于微信公众号(蛋蛋的区块链笔记):钓鱼这样才好玩 — 记一次有意思的钓鱼样本分析

版权声明:admin 发表于 2022年9月9日 下午6:17。
转载请注明:钓鱼这样才好玩 — 记一次有意思的钓鱼样本分析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...