相关信息

KaoyaSwap 是 BSC 链上的一个自动做市商 AMM。然后,现在他们的官网 https://www.kaoyaswap.com/ 已经打不开了(如果我打开方式没错的话)。所以就直接进行攻击事件的分析吧。

攻击交易:https://bscscan.com/tx/0xc8db3b620656408a5004844703aa92d895eb3527da057153f0b09f0b58208d74

攻击者在进行攻击之前,自己构建了两个代币协助完成攻击,下面将他们分别称为 TA 和 TB 。

TA address:0x74eF69Defe8bae1Fe660fB93265FC1bc79c9bDa8

TB address:0xD84379C4eeA25d05574f9F0B99E3Bf73500Ca4B4

交易流程

因为攻击是发生在 AMM 上的,所以我们可以根据代币的流向先大概分析一下攻击者在这笔交易中都做了些什么,看看能不能看出有什么奇怪的地方。下面绿色框图是 Tokens Transferred 的内容,红色框图的是 Internal Txns 的内容。

  1. 首先闪电贷 1800 BNB
  2. 调用 swapExactTokensForTokens 函数,用 672 BNB 换出 125023 KY
  3. 调用 swapExactTokensForTokens 函数,用 100 BNB 换出 6666 BUSD
  4. 调用 addLiquidity 函数,添加 1026 BNB 和 50 TA,获得 226 KALP 流动性代币

  1. 调用 addLiquidity 函数,添加 1 BNB 和 1 TB,获得 0.9 KALP 流动性代币
  2. 调用 addLiquidity 函数,添加 1 TA 和 1 TB,获得 0.9 KALP 流动性代币

  1. 调用 swapExactTokensForETHSupportingFeeOnTransferTokens 函数,其中 path 参数为 [TA, WBNB, TB, TA, WBNB] 的地址。这个函数还涉及到 BNB 的转账,但是函数 Output 中没有体现。(剧透一下,转出了 1019 BNB 给攻击地址。具体情况后面的代码分析会解释)。
Input:
"amountIn": "8000000000000000000000",
"amountOutMin": "1",
"path": [
"0x74ef69defe8bae1fe660fb93265fc1bc79c9bda8",
"0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c",
"0xd84379c4eea25d05574f9f0b99e3bf73500ca4b4",
"0x74ef69defe8bae1fe660fb93265fc1bc79c9bda8",
"0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"
],
"to": "0xa722ca7bf032de8f7a675da75dfec661bc89ace9",
"deadline": "1661293930“ Output:
0x

  1. 调用 removeLiquidityETHSupportingFeeOnTransferTokens 函数,销毁 226 KALP,获得 8050 TA,Output "amountETH": "6392515470500594443"
  2. 调用 removeLiquidityETHSupportingFeeOnTransferTokens 函数,销毁 0.9 KALP,获得 0.0009 TB,Output "amountETH": "1020797089459256392608"

  1. 调用 removeLiquidity 函数,传入 0.9 KALP,获取 0.5 TA 和 1.9 TB
  2. 调用 swapExactTokensForTokens 函数,传入 83918 KY,获得 25170 BUSD

  1. 在 pancakeswap 中把 17740 KY 换成 5457 BUSD,把 23364 KY 换成 24 WBNB。
  2. 归还 1800 WBNB 闪电贷。
  3. 然后把 37294 BUSD 和 271 WBNB 转移到 0xd87f 地址中

总的来看,攻击者主要投入了 1026 BNB 到 WBNB 和 TA 的池子中,然后通过 swapExactTokensForETHSupportingFeeOnTransferTokens 函数以 8000 TA 获得 1019 BNB,并且通过 removeLiquidityETHSupportingFeeOnTransferTokens 函数移除 WBNB 和 TB 池子的流动性获得 1020 BNB。

投入 1026 BNB,获得 (1019 + 1020) BNB,其中必有蹊跷。

代码分析

首先来分析一下 swapExactTokensForETHSupportingFeeOnTransferTokens 函数,先调用 _transferIn 转入 TA,然后调用 _swapSupportingFeeOnTransferTokens 函数按照 path 进行一系列 swap 操作,计算 _pools[TA,WBNB][WBNB] 的变化,根据差值给 to 地址发送相等数量的 BNB。

需要关注的函数:_transferIn_swapSupportingFeeOnTransferTokens。这些函都涉及到了一个关键的变量 _pools ,它是这次攻击的关键点。

先来看 _transferIn 函数,它的作用是把 path 中的第一个代币转入合约中,并修改对应的 _pools 值。

_swapSupportingFeeOnTransferTokens 函数根据 path 所提供的代币地址进行 swap,并将对应的 _pools 变量进行修改。

其中 _transferOut 函数的作用就是向 to 地址发送 amount 数量的 token。

swapExactTokensForETHSupportingFeeOnTransferTokens 函数中 path = [TA, WBNB, TB, TA, WBNB] 时所发生的情况是(下面简称 [A, W, B, A, W]):

首先在 _transferrIn 函数中:

_pool[AW][A] + amountIn

然后在 _swapSupportingFeeOnTransferTokens 函数中(注意 _pool[AW][W] 做了两次减法操作):

i = 0 , _pool[AW][W] – amountOutput1, _pool[WB][W] + amountOutput1
i = 1 , _pool[WB][B] – amountOutput2, _pool[BA][B] + amountOutput2
i = 2 , _pool[BA][A] – amountOutput3, _pool[AW][A] + amountOutput3
i = 3 , _pool[AW][W] – amountOutput4

转账的金额只通过最后一对 pair_pool 数值 _pool[AW][W] 的减少量(从 AW 这个池子里换出了多少 W)来确定。正确的方法应该是只关注最后一步中 _pool[AW][W] 的减少量,而不是整个 swap 过程中 _pool[AW][W] 的总(累计)减少量。如果采用总(累计)减少量计算,则当 path 中有重复的 pair ([A, W])不连续出现时,会多次计算 _pool[AW][W] 的减少量,最终导致 balanceBefore.sub(balanceAfter) 的值大于实际值。

我们看到第 1 次 TA 换 WBNB 的时候,换出来 1019.797089459257413406 WBNB,第 2 次 TA 换 WBNB 的时候,换出来 0.000395070241992122 WBNB,累加得到 1019.797484529499405528 WBNB,吻合之前提到的值。而正常情况下应该转出的 WBNB 因该为 0.000395070241992122 WBNB,同时将 [WBNB, TB] 池子中 TB 的币价大幅提高(转入了大量 WBNB)。

综上所属,利用了 _pools 变量在整个 swap 过程中累计减少量的漏洞,攻击者用一笔钱,在提高了 [WBNB, TB] 池子中 TB 的币价的同时, swap 出了超量的 WBNB。然后再移除 [WBNB, TB] 池子的流动性, 获取大量的 BNB。

【漏洞分析】KaoyaSwap 安全事件分析的更多相关文章

  1. CVE-2013-2551漏洞成因与利用分析(ISCC2014 PWN6)

    CVE-2013-2551漏洞成因与利用分析 1. 简介 VUPEN在Pwn2Own2013上利用此漏洞攻破了Win8+IE10,5月22日VUPEN在其博客上公布了漏洞的细节.它是一个ORG数组整数 ...

  2. CVE-2014-0322漏洞成因与利用分析

    CVE-2014-0322漏洞成因与利用分析 1. 简介 此漏洞是UAF(Use After Free)类漏洞,即引用了已经释放的内存,对指定内存处的值进行了加1.其特点在于攻击者结合flash实现了 ...

  3. CVE-2013-3897漏洞成因与利用分析

    CVE-2013-3897漏洞成因与利用分析 1. 简介 此漏洞是UAF(Use After Free)类漏洞,即引用了已经释放的内存.攻击者可以利用此类漏洞实现远程代码执行.UAF漏洞的根源源于对对 ...

  4. 漏洞分析:OpenSSH用户枚举漏洞(CVE-2018-15473)分析

    漏洞分析:OpenSSH用户枚举漏洞(CVE-2018-15473)分析 漏洞分析:OpenSSH用户枚举漏洞(CVE-2018-15473)分析 - FreeBuf互联网安全新媒体平台 https: ...

  5. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  6. Memcached源代码分析 - Memcached源代码分析之消息回应(3)

    文章列表: <Memcached源代码分析 - Memcached源代码分析之基于Libevent的网络模型(1)> <Memcached源代码分析 - Memcached源代码分析 ...

  7. mysql 分析3使用分析sql 性能 show profiles ;

    show variables like '%profiling%';    查看状态  查看时间去哪了``` set  profiling=1;// 打开 show profiles;  查看执行过的 ...

  8. [转载] 常用 Java 静态代码分析工具的分析与比较

    转载自http://www.oschina.net/question/129540_23043 简介: 本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代 ...

  9. x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

随机推荐

  1. JS:对象调方法1

    找调用者 1.如果有this,就先看this在哪个函数中,就是离this最近的function,没有就是window 2.找到函数后,辨别哪个是调用者 例1: 点击查看代码 function fn() ...

  2. Vscode个性化设置:让一个小萌妹陪你敲代码

    前言 大家平时都用什么代码编辑器啊!我个人比较喜欢用vscode,因为有以下几点: 开源,免费: 自定义配置 集成git 智能提示强大 支持各种文件格式(html/jade/css/less/sass ...

  3. 入门Python数据分析最好的实战项目(一)分析篇

    数据初探 首先导入要使用的科学计算包numpy,pandas,可视化matplotlib,seaborn,以及机器学习包sklearn. python学习交流群:660193417### import ...

  4. 【.NET+MQTT】.NET6 环境下实现MQTT通信,以及服务端、客户端的双边消息订阅与发布的代码演示

    前言: MQTT广泛应用于工业物联网.智能家居.各类智能制造或各类自动化场景等.MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,在很多受限的环境下,比如说机器与机器通信.机器与物联网通信等. ...

  5. Java开发学习(八)----IOC/DI配置管理第三方bean、加载properties文件

    前面的博客都是基于我们自己写的类,现在如果有需求让我们去管理第三方jar包中的类,该如何管理? 一.案例:数据源对象管理 本次案例将使用数据源Druid和C3P0来配置学习下. 1.1 环境准备 学习 ...

  6. 密码学系列之:在线证书状态协议OCSP详解

    目录 简介 PKI中的CRL CRL的缺点 CRL的状态 OCSP的工作流程 OCSP的优点 OCSP协议的细节 OCSP请求 OCSP响应 OCSP stapling 总结 简介 我们在进行网页访问 ...

  7. C++学习日记:关于我决定开始学习C++的那些事

    苦恼于Python运行时感人的速度,我决定学习C++. 为了激励我自己好好地学习这门未曾谋面的编程语言,我决定在此开设专栏:C++学习日记.希望在读者们的监督下,我可以早日掌握这门语言.当然,如果那位 ...

  8. 输入一个url全过程详解

    1. 用户在浏览器中输入url,浏览器接收到url. 2.浏览器接收到这个url之后,会根据这个url会先查看缓存,如果有缓存且没有过期的话直接提供给客户端,完成页面渲染. 3.否则浏览器就会通过DN ...

  9. excel网络函数库之谷歌翻译

    不知道看到本篇文章的小伙伴是否被表格翻译所困扰,当面对大量需要被翻译的文件内容,有着三头六臂的孙悟空也难以招架得住,那么有没有一个工具能让我们快速将大量文件进行翻译呢? ExcelApi函数库的横空出 ...

  10. RabbitMQ细说之开篇

    前言 关于消息中间件的应用场景,小伙伴们应该都耳熟能详了吧,比如经常提到的削峰填谷.分布式事务.异步业务处理.大数据分析等等,分布式消息队列成为其中比较关键的桥梁,也就意味着小伙伴们得掌握相关技能:当 ...