在本篇文章中,我将通过一个攻击事件引出 Reflection Token 攻击事件的一个通用分析思路。

关于 Reflection Token 的其他案例分析,可以参考BEVO代币攻击事件分析及复现一文。

TomInu 攻击事件

TomInu Token 是一个反射型代币 reflection token,于2023-01-26遭到黑客攻击,攻击者获利35577美元。

TomInu(被攻击合约): 0x2d0e64b6bf13660a4c0de42a0b88144a7c10991f

攻击交易: https://phalcon.blocksec.com/tx/eth/0x6200bf5c43c214caa1177c3676293442059b4f39eb5dbae6cfd4e6ad16305668

攻击过程较为简单,攻击者通过几个常规操作就完成获利。

  1. 攻击者借出闪电贷
  2. 用 WETH swap 出 1465904852700232013011 TINU
  3. deliver 1465904852700232013011 TINU
  4. skim 得到 1733770910894426471783 TINU(在这一步已经完成了获利)
  5. 把 TINU swap 为 WETH
  6. 归还闪电贷

本次攻击事件通过推文告警并且进行了分析,但是很可惜分析的结论略显含糊的。红框标注的部分并不是攻击者获利的真正原因。(为什么不是真的)

推文:https://twitter.com/QuintenDes/status/1618730379447508998

并且,目前在在网络上搜索到的所有关于 reflection token 攻击事件的成因分析中提到:“由于攻击者 deliver 了一笔 token ,导致了 pair 中的 token 升值,从而能够 skim 出更多的 token 进行获利”。这类分析大多是理所当然地下结论,没有通过实际的计算推导,妄下结论误导读者。(为什么这么说)

攻击过程很简单,先 deliver 然后 skim,就能够获利了。根据这个攻击过程的特征,我们直接找 rToken增发代码,定位漏洞点。(为什么可以这么做)

以上的几个为什么都将会在后面“为什么”这一章节进行解释,读者可以先带着疑问进行阅读。

漏洞分析

_transferStandard 函数中可以看出,TomInu 代币在进行转账 rAmount 时需要收取 teamfee 两种手续费,并将扣除了手续费后的 rTransferAmount 转给收款人。

其中 team 手续费 rteam 留存在本合约中,fee 手续费 rfee 则是直接销毁。

此时他们的数量关系应该为:rTransferAmount = rAmount - rteam - rfee

问题出现在 _getRValues 函数中,该函数在计算 rTransferAmount 的过程中忽略了 rteam 参数,计算 rTransferAmount = rAmount - rfee 得到的结果比实际结果要大,造成了 rToken 的增发。也就是说,因为这个计算问题,市场上实际流通的 rAmount 总和是要大于 rTotal 的值的。

代币合约在执行 _transfer() 函数的时候,会将本合约的代币 swap 成 ETH,这个操作使得增发的代币一直累计在 pair 中。

为什么

在这个章节中,会对前面的暴言暴论进行解释

  1. 为什么推文中的关于漏洞成因的结论是含糊的不准确的。
  2. 什么说关于 reflection token 攻击事件的成因分析中提到“由于攻击者 deliver 了一笔 token ,导致了 pair 中的 token 升值,从而能够 skim 出更多的 token 进行获利”的分析结论都是错误的。
  3. 为什么看到攻击过程先 deliver 然后 skim 就完成获利之后,我得出的结论是直接找 rToken增发代码定位漏洞点。

首先我将举几个例子来模拟整个 deliver-skim 的过程,为了使得这个例子尽可能的简单,这个过程中将不考虑任何手续费的收取。

场景1:

只有 attacker 和 pair 持有所有的 token

rTotal 1000, tTotal 100, rate 10

pair: rAmount 500, tAmount 50
attacker: rAmount 500, tAmount 50

attacker deliver 500 rAmount

rTotal 500, tTotal 100, rate 5

pair: rAmount 500, tAmount 100
attacker: rAmount 0, tAmount 0

此时,pair 的 tAmount 从 50 变成了 100。接下来 attacker 将调用 skim 来获利了是不是?

attacker calls pair.skim()

rTotal 500, tTotal 100, rate 5

pair: rAmount 250, tAmount 50
attacker: rAmount 250, tAmount 50

attacker 如愿以偿获利了吗?没有,attacker 和 pair 又回到了最初的 50 tAmount,并不能通过这个操作来进行获利。

场景2:

attacker, pair 以及一些其他用户共同持有所有的 token

rTotal 1000, tTotal 100, rate 10

pair: rAmount 250, tAmount 25
attacker: rAmount 500, tAmount 50
others: rAmount 250, tAmount 25

attacker deliver 500 rAmount

rTotal 500, tTotal 100, rate 5

pair: rAmount 250, tAmount 50
attacker: rAmount 0, tAmount 0
others: rAmount 250, tAmount 50

attacker calls pair.skim()

rTotal 500, tTotal 100, rate 5

pair: rAmount 125, tAmount 25
attacker: rAmount 125, tAmount 25
others: rAmount 250, tAmount 50

pair 回到了原始的 25 tAmount,而 attacker 由原来的 50 亏损到了 25 tAmount。坚定持有的 others 由 25 上涨到了 50 tAmount。

通过上面的两个例子,我们可以得出结论,只有当 attacker 和 pair 所持有的代币份额合计 100% 的情况下,deliver-skim 的操作 attacker 才不会亏损。而两者份额不足 100% 的情况下,deliver-skim 的操作反而会导致 attacker 遭受损失。也就是说 attacker 通过 deliver-skim 的操作无论怎么样都是不赚的,最好的情况是 attacker 和 pair 所持有的代币份额合计 100% 的情况下才不至于亏损。

那么…有没有更好的情况呢?好到…两者持有的代币份额合计起来…超过100%

比如,发生了代币增发?

场景3:

由于代码存在 rToken 相关的计算错误,导致代币增发的发生,具体表现为 rToken 的实际流通量大于 rTotal 的数量。

rTotal 1000, tTotal 100, rate 10

pair: rAmount 400, tAmount 40
attacker: rAmount 800, tAmount 80
others: rAmount 400, tAmount 40 sum_rAmount = 1600 > rTotal = 1000
pair.rAmount + attacker.rAmount = 1200 > rTotal = 1000

attacker deliver 800 rAmount

rTotal 200, tTotal 100, rate 2

pair: rAmount 400, tAmount 200
attacker: rAmount 0, tAmount 0
others: rAmount 400, tAmount 200

attacker calls pair.skim()

rTotal 200, tTotal 100, rate 2

pair: rAmount 80, tAmount 40
attacker: rAmount 320, tAmount 160
others: rAmount 400, tAmount 200

至此,attacker 从原来的 80 tAmount,通过 deliver-skim 操作获利达到 160 tAmount。

通过这个场景,也就可以解释为什么看到攻击过程中通过 deliver-skim 操作获利时,首先想到的就是去找代码中使得 rAmount 增发的计算操作。因为只有 rAmount 发生了增发,pair 和 attacker 的份额大于 100%,且增发部分需要留存在 pair 合约中,才能够满足通过 deliver-skim 操作进行获利的基础条件。

后记

在 TomInu 攻击事件发生的4个月后,存在相同漏洞的 ADU token 再次被攻击。

ADU token attack tx:https://explorer.phalcon.xyz/tx/bsc/0xc6f6b70e9e35770b699da9b60244d461d02db66859df42319c3207d76931423c

为什么会写这篇文章,因为当我想对这些攻击事件进行学习与分析的时候,我查看了网络上的分析文章,他们给出的漏洞成因含糊不清毫无根据。我读了很多篇分析文章,说辞都是大同小异地糊弄。还没分析清楚就胡乱指点,最终被忽悠的就是真心想研究清楚的人。走了不少弯路,把弯路总结成这篇文章,感谢你的阅读。

【漏洞分析】Reflection Token 反射型代币攻击事件通用分析思路的更多相关文章

  1. 以太坊钱包开发系列4 - 发送Token(代币)

    以太坊去中心化网页钱包开发系列,将从零开始开发出一个可以实际使用的钱包,本系列文章是理论与实战相结合,一共有四篇:创建钱包账号.账号Keystore文件导入导出.展示钱包信息及发起签名交易.发送Tok ...

  2. Go-Ethereum 1.7.2 结合 Mist 0.9.2 实现代币智能合约的实例

    目录 目录 1.什么是 Mist 2.Mist 在哪里下载? 3.Mist 有哪些依赖? 4.如何安装 Mist? 4.1.安装 Mist 依赖工具包 4.2.安装 Mist 4.3.启动 Mist, ...

  3. AMR无限增发代币至任意以太坊地址的漏洞利用及修复过程

    AMR无限增发代币至任意以太坊地址的漏洞利用及修复过程 0x00 项目简述 Ammbr主要目标是打造具有高度弹性且易于连接的分布式宽带接入平台,同时降低上网相关成本.Ammbr打算创建具有人工智能和智 ...

  4. Facebook币Libra学习-6.发行属于自己的代币Token案例(含源码)

    在这个简短的概述中,我们描述了我们在eToro标记化资产背后实施技术的初步经验,即MoveIR语言中的(eToken),用于在Libra网络上进行部署. Libra协议是一个确定性状态机,它将数据存储 ...

  5. STO(Security Token Offering)证券型通证、代币发行介绍

    STO(Security Token Offering)证券型通证.代币发行介绍:STO(Security Token Offering)是一个新的融资概念.通过证券化的通证进行融资.早在2017年年 ...

  6. 通过以太坊发行代币(token)

    2017年开始,区块链ICO项目层出不穷,市场热度一波更胜一波,很多ICO都是通过以太坊智能合约发行自己的代币(token),具体怎样才能发行代币呢?本文进行具体详细的介绍. 准备工作 以太坊官网ER ...

  7. 区块链代币(Token)笔记 — — 术语

    前言 接触区块链和数字货币差不多有大半年时间,一直在赶项目进度,现在有空整理补习一下相关的知识,只谈代币不谈区块链

  8. 证券化代币的时代已经到来,STO将引爆区块链经济

    STOs 似乎会在 2019 年取代 ICOs,即使不是完全取代,但置换的比例也会相当大.所有在美上市的公司都将按照 SEC 制定的相关规定进行交易.Vellum Capital 的 CEO 兼管理合 ...

  9. MakerDAO 代币解释:DAI, WETH, PETH, SIN, MKR(一)

    Maker DAO Token Maker DAO 系统是由多个智能合约 ( Sai Tap, Sai Tub, Vox, Medianiser, etc.), 和 ERC-20 代币组成. 他们一起 ...

  10. 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[3]:自定义代币

    原文作者:Xuejie 原文链接:https://xuejie.space/2019_09_06_introduction_to_ckb_script_programming_udt/ Nervos ...

随机推荐

  1. 《SQLi-Labs》03. Less 11~15

    @ 目录 索引 Less-11 题解 原理 Less-12 题解 Less-13 题解 Less-14 题解 Less-15 题解 原理 sqli.开启新坑. 索引 Less-11:POST 回显注入 ...

  2. 《SQL与数据库基础》18. MySQL管理

    目录 MySQL管理 系统数据库 常用工具 mysql mysqladmin mysqlbinlog mysqlshow mysqldump mysqlimport source 本文以 MySQL ...

  3. SpringBoot整合ueditor编辑器

    1.到ueditor编辑器官网下载jsp版(目前官网地址改为了GitHub)https://ueditor.baidu.com/website/download.html2.下载解压后复制到当前项目3 ...

  4. mysql8关闭binlog并清空Binlog

    编辑my.ini或者my.cnf文件 清空binlog信息 #查看现存的binlog文件列表 show master logs; #重置清空binlog文件 reset master; #重置清空后 ...

  5. 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(1)

    在我们的SqlSugar的开发框架中,整合了Winform端.Vue3+ElementPlus的前端.以及基于UniApp+Vue+ThorUI的移动前端几个前端处理,基本上覆盖了我们日常的应用模式了 ...

  6. Vika and Her Friends

    Smiling & Weeping ----早知道思念那么浓烈,不分手就好了 题目链接:Problem - A - Codeforces 题目大意:有n个Vika的朋友在一个n*m的方格中去捉 ...

  7. KRPANO开发拍摄拼图视频常用软件分享

    KRPano开发拍摄拼图视频常用软件分享,包含了KRPano开发,拼图,视频等软件. 包括如下软件: 全景照片拼接,全景照片查看,全景视频拼接,全景视频查看,全景视频插件,全景漫游制作,KRPano资 ...

  8. 01.前后端分离中台框架后端 Admin.Core 学习-介绍与配置说明

    中台框架后端项目 Admin.Core 的介绍与配置说明 中台admin是前后端分离权限管理系统,Admin.Core为后端项目,基于.NET 7.0开发. 支持多租户.数据权限.动态 Api.任务调 ...

  9. Docker V24 及 Docker Compose V2 的安装及使用

    前言 Docker 是一款流行的开源容器化平台,使用 Docker 可以有效地隔离应用程序和系统环境,使得应用程序在不同的环境中具有相同的行为 Docker Compose 是一个用于定义和管理多个 ...

  10. LeetCode 周赛上分之旅 #49 再探内向基环树

    ️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...