SHOCO攻击分析

  • KEN
  • 发布于 10小时前
  • 阅读 21

攻击相关事件2023年1月19日,Ethereum主网上的通缩代币项目SHOCO被攻击,并且由于初始的攻击者没有利用MEV和flashbots,而是将该攻击交易通过公用的交易池进行打包上链,但是在该交易被送进交易吃的瞬间,链上的MEV机器人就瞬间分析出该交易是一笔攻击交易,并且复制了该攻击交易的全

攻击相关事件

2023年1月19日,Ethereum主网上的通缩代币项目SHOCO被攻击,并且由于初始的攻击者没有利用MEV和flashbots,而是将该攻击交易通过公用的交易池进行打包上链,但是在该交易被送进交易吃的瞬间,链上的MEV机器人就瞬间分析出该交易是一笔攻击交易,并且复制了该攻击交易的全部信息并将收益地址更改为抢跑者,最后通过MEV对初始的攻击交易进行抢跑,最后抢跑者获利约4.3 ETH($14000)。 Total lost: 4.3 ETH 初始攻击者: 0x14d8ada7a0ba91f59dc0cb97c8f44f1d177c2195 攻击合约: 0x15d684b4ecdc0ece8bc9aec6bce3398a9a4c7611 被攻击合约: 0x31A4F372AA891B46bA44dC64Be1d8947c889E9c6 抢跑者:0xe71aca93c0e0721f8250d2d0e4f883aa1c020361 抢跑机器人:0x000000000000660deF84E69995117c0176bA446E 抢跑攻击:0x2e832f044b4a0a0b8d38166fe4d781ab330b05b9efa9e72a7a0895f1b984084b 下图中展示了抢跑交易攻击的具体交易细节:

image.png

攻击前的准备工作

我们详细阅读了整个SHOCO_exp.sol文件。这个合约文件展示了一个针对SHOCO代币的攻击过程,攻击者通过调用deliver函数销毁自己的SHOCO代币,使得Uniswap交易对中的SHOCO代币数量增加,然后利用skim函数将这些增加的代币转移回自己的账户,重复上述过程直到满足一定条件,再调用swap函数将累积的SHOCO代币换成ETH,并通过抢跑机器人支付更高的交易费让矿工提前打包交易以完成攻击,最终记录攻击的利润或损失。 最后,我们对抢跑机器人进行反编译如下图所示:

image.png 该项目是一个利用反射机理的通缩代币项目,一般来说在该种类型的项目中往往存在一个特性,即当某个通缩代币持有者销毁其通缩代币时,项目为了奖励该种类型代币的持有者,会自动的增加代币持有者的余额,但不会触发转账,只是修改一个系数。在这个机制中,用户持有的代币数量有两种,分别为tAmount和rAmount。tAmount为实际持有的代币数量,rAmount为体现的代币数量,比例为tTotal/rTotal。反射机制的token 一般都有一个叫deliver的函数,这个函数会销毁调用者的 token,降低 rTotal 的值,所以比例会增加,其他用户反射的token数量也会增加,攻击者注意到了该功能,并利用该功能对相应的 Uniswap 进行攻击,在Uniswap中,reserve就是储备资金,它和token.balanceOf(address(this))有区别。攻击者首先调用 deliver 函数销毁自己的 token,导致rTotal的值减小,比例增大,因此反射出来的token的值也会增大,token.balanceOf(address(this)) 也会随之增大,导致和储备值出现差距。因此攻击者可以通过调用skim函数转移两个token之间的差额来获利。

攻击具体分析

首先,我们分析了造成此次攻击事件的攻击的资金具体流向,如下图所示。

image.png 简单分析机器人的攻击交易以及原始的攻击合约,可以发现本次攻击与TINU类似,但攻击者使用了更为复杂的skim->deliver调用链。

image.png 值得一提的是,原始攻击者并没有使用Flashbots的隐私服务来发送攻击,代码只进行了验证msg.sender,这使得发起的交易容易受到抢先交易的攻击。

image.png 然而,该机器人使用Flashbots发起交易,向Builder贿赂0.09以太币,最终获利约4.067以太币。

image.png 攻击结束后,rTotal下降,tFeeTotal上升,说明该漏洞应该与TINU一致。显然,实际获利4.3 Ether比最初攻击的约4.16 Ether略多。因此,在进一步检查SHOCO代币后发现,与Nomad Bridge攻击相关的人,在一个月后又对其发起了另一次攻击。另外可以观察到,所使用的攻击合约是由另一个地址0x961C44Acf3198Da23e289445D3dB6a7531890b50部署的,由于其合约没有任何保护措施,因此直接被0x1dbd使用来完成抢先交易。 其次,我们来具体分析整个攻击事件的调用过程,深入理解攻击的内核原因,如下图所示。

image.png

image.png 从具体调用我们可以了解到整个事件攻击的整体步骤如下: Step1.通过sentio对该攻击交易进行分析发现,攻击的流程,主要是通过不断地deliver销毁攻击者自己的shoco代币,使得pair中的shoco代币不断增加,并迅速地调用skim将pair中增加的shoco代币转移回来。这个过程,攻击者的shoco代币数量会一直增加。 Step2.由于deliver函数获利的条件是需要满足不等式:y(1/rate - 1)> x,其中y是pair中的shoco代币数量,rate是被攻击合约中的tSupply/rSupply,x是攻击者销毁的代币数量,所以攻击者一直重复上述的过程直到不等式被打破。 Step3.攻击者调用swap函数,将pair中不断累积的shoco代币全部置换为ETH,至此攻击完成。 Step4.抢跑,相比于最初始的攻击交易的交易费0.005251913355283232ETH,该抢跑机器人给了矿工0.09ETH,让矿工提前打包自己的交易,完成攻击。 最后,我们展示了根据分析得到的交易信息,下图为它的详细信息:

image.png

image.png

攻击事件复现

Step1.Foundry环境准备:

image.png Step2.代码复现: 我们在本地复现了攻击案例的整个流程,在攻击过程中我们模拟攻击者原地址为整个交易的发起者,这样可以使得攻击合约中某些条件检测得以通过,我们编写了自己的攻击合约来复现整个交易流程: 下图为配置的实验环境。我们设置了一个接口IReflection,继承自IERC20,并定义了两个函数:deliver用于销毁指定数量的代币,tokenFromReflection用于根据反射量计算代币数量;合约SHOCOAttacker继承自Test,并初始化了三个变量,分别表示Uniswap的SHOCO-WETH交易对(shoco_weth),SHOCO代币合约(shoco),以及WETH代币合约(weth),通过设置这些接口和变量,合约可以与SHOCO代币和Uniswap交易对进行交互。 我们定义了testExploit函数用于模拟和执行一次针对SHOCO代币的攻击。首先,函数将当前的区块高度设置为attackBlockNumber以模拟特定的区块链状态,然后使用vm.rollFork函数切换到该区块高度,并记录攻击前合约地址的WETH余额,通过console.log和emit log_named_decimal_uint函数输出WETH余额,如下图所示。

image.png

image.png 我们将上述函数作为整个攻击交易的入口, 注意我们并没有像攻击交易一样做了那么多deliver与skim操作,我们是直接跳过了前面的金钱累计操作,直接进行了最后的deliver(因为在靶场上我们能够用作弊码让我们直接拥有足够的资金),如下图所示。 在testExploit函数中,首先输出在shoco_weth交易对中SHOCO代币的初始余额,然后调用deliver函数销毁几乎所有的SHOCO代币,从而增加交易对中的SHOCO代币数量,并再次输出shoco_weth交易对中SHOCO代币的余额以查看变化。

image.png

复现最后效果

运行我们设计的复现脚本,可以看到如下图所示的攻击结果,从图中可以看到,在进行攻击之前,账户的余额是没有WETH的,在进行攻击之后,可以发现账户的余额多出了WETH,也就说明获利了4.3WETH,从而证明实现了抢先交易攻击,如图所示。

image.png 同时,在更加详细的打印的log信息中可以发现,代币之间具体的转换情况和变化。

image.png

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
KEN
KEN
0x4e16...2573
江湖只有他的大名,没有他的介绍。