Discover项目遭到闪电贷攻击详解

  • SpikeDu
  • 发布于 1天前
  • 阅读 121

Hardhat 复现详细解析了 Discover 项目的闪电贷攻击,通过 攻击者合约的分析、交易执行流程的重现,以及时序图展示,完整还原了攻击过程。

一、什么是闪电贷攻击?详解 DeFi 生态中的金融攻击手法

1. 引言

闪电贷(Flash Loan)是 DeFi 生态中一种创新的金融工具,它允许用户在单笔交易中借入大量资金,并在交易结束前归还,无需提供抵押。这种机制极大降低了资金运作成本,同时也为攻击者提供了新的套利手段。闪电贷攻击便是利用该特性,结合智能合约漏洞,对 DeFi 平台进行恶意操纵的一种攻击方式。

2. 闪电贷攻击的分类

闪电贷攻击主要分为两类:

image.png

  1. 基于询价机制的攻击
  2. 基于合约漏洞的攻击

2.1 基于询价机制的闪电贷攻击

去中心化交易所(DEX)和借贷协议通常采用某种询价机制(Pricing Mechanism)来确定资产价格。然而,这种机制的单一性使其容易被操纵,尤其是在大额交易的影响下,价格会产生剧烈波动。过去,此类攻击需要大量资金支撑,而闪电贷的出现降低了攻击门槛,使得攻击者可以在零成本的情况下操纵市场。

攻击流程

基于价格操纵的闪电贷攻击一般包括以下四个步骤:

image.png

  1. 闪电贷借款

    • 攻击者通过闪电贷借出大量资金,获得用于操纵市场的资产 A存储攻击目标资产 B
  2. 抵押资产

    • 攻击者将资产 B 抵押到目标协议中,以获得一定的借贷额度。
  3. 操纵市场价格

    • 利用资产 A 进行大额交易,人为抬高或压低目标资产 B 的价格,影响其在资金池或借贷平台上的估值。
  4. 获利并归还贷款

    • 由于资产 B 价格被操纵,其抵押品估值上升,攻击者趁机将高估值的抵押品兑换回 B 资产,再将借款归还闪电贷合约,赚取套利利润

2.2 基于合约漏洞的闪电贷攻击

除了操纵价格外,闪电贷还可用于放大基于智能合约漏洞(如重入漏洞、定价错误、整数溢出等)的攻击。例如,在正常情况下,攻击者可能因资金有限而无法利用某些漏洞获利,而闪电贷提供的大额资金让攻击者可以执行更大规模的攻击,放大潜在损失

攻击成因

闪电贷攻击的发生通常与以下因素有关:

  • 超高的资金量:攻击者无需自有资金,即可获取大额资产,放大攻击损失
  • 智能合约漏洞:借贷协议或 DEX 代码中的逻辑缺陷可被利用,成为攻击入口。
  • 去中心化金融(DeFi)的开放性:不同 DeFi 项目之间缺乏宏观监管,代码 Fork 现象严重,使得一个漏洞可能影响多个协议。

3. 真实攻击案例分析

3.1 bZx 攻击事件(2020.02.15)

事件概述

  • 区块高度:9484688
  • 攻击方式:利用闪电贷操纵价格
  • 攻击目标:bZx 资金池
  • 获利金额:1271.4 ETH(约 35 万美元)

攻击者使用闪电贷借入资金,在 bZx 交易池中执行大额交易,人为制造价格异常,使 bZx 在借贷时错误评估资产价值,从而获利。这是史上首例利用闪电贷的 DeFi 价格攻击,之后类似攻击事件频发。


3.2 Discover 项目攻击(2022.06.06)

攻击手法: 本次攻击者结合闪电贷与预言机操纵,利用闪电贷借出大量资金,在PancakeSwap 交易池中进行交易,推高目标代币价格,进而利用该价格变化进行套利。

攻击流程

  1. 闪电贷借款

    • 攻击者从 PancakeSwap 交易池借出 2100 USDT 和 19000 USDT。
  2. 操纵市场

    • 在 Discover 项目中,USDT 价格依赖 PancakeSwap 交易池。攻击者利用借来的 USDT 进行大额买入,人为抬高 USDT 价格
  3. 利用抵押套利

    • 由于 Discover 的借贷合约使用 USDT 价格作为抵押计算基准,USDT 价格上涨后,攻击者能借出更多 Discover 代币
  4. 市场价格回调

    • 攻击者归还闪电贷,恢复市场价格,但已持有大量 Discover 代币。
  5. 套利退出

    • 攻击者将 Discover 代币换回 USDT,并兑换成 BNB 进行混币,完成套利。

攻击信息

  • 攻击者钱包0x446247bb10B77D1BCa4D4A396E014526D1ABA277
  • 攻击合约0x06B912354B167848a4A608a56BC26C680DAD3D79
  • 攻击交易BSC 交易详情
  • 被攻击合约:ETHpledge(0x5908E4650bA07a9cf9ef9FD55854D4e1b700A267
  • 攻击获利:49 BNB(约 27600 美元)

4. 为什么闪电贷攻击愈演愈烈?

闪电贷攻击的频率和影响范围不断扩大,主要有以下原因:

  1. 攻击门槛低

    • 传统价格操纵需要巨额资本,闪电贷让攻击者几乎零成本发动攻击。
  2. 攻击规模大

    • 闪电贷允许借出极大资金量,导致攻击影响加剧。
  3. 代码 Fork 现象严重

    • 例如,2021 年 BSC 上的 AutoShark、Merlin、Bunny 三个平台先后遭遇相同攻击手法,因为它们的代码高度相似,导致攻击模式可以快速复制。
  4. 去中心化金融的组合性

    • DeFi 应用往往是多个智能合约的组合,漏洞的风险可能在不同协议间相互传递。

5. 如何防御闪电贷攻击?

5.1 预防价格操纵攻击

  • 提高资金池流动性:防止大额交易对价格造成剧烈影响。
  • 优化预言机机制:采用多数据源预言机,避免单点数据操纵。
  • 延迟价格更新:设置时间缓冲,防止瞬时操纵。

5.2 预防智能合约漏洞

  • 代码审计:严格检查智能合约的安全性,减少漏洞。
  • 限制单笔交易影响范围:对借款额度、交易量设置上限。
  • 启用攻击检测:监控交易行为,识别异常模式。

二、闪电贷攻击案例分析:Discover 项目攻击(2022.06.06)

1. 案例背景

2022 年 6 月 6 日,Discover 项目 遭遇 闪电贷攻击,攻击者巧妙地结合了闪电贷与预言机价格操纵,利用大额资金短时间内在去中心化交易池(PancakeSwap)中进行交易,人为推高目标代币价格,从而实现套利。这属于基于询价机制的闪电贷攻击

可以简单理解为:

攻击者通过快速借贷(闪电贷)获取大量资金,在 PancakeSwap 交易所中大量购买 Discover 代币(萝卜),抬高其价格,再利用高估值的 Discover 代币进行抵押借贷,从而获得利润。


2. 背景知识:PancakeSwap 交易机制

2.1 去中心化交易池的运作

PancakeSwap 采用自动化做市商(AMM)模型,其交易池本质上是包含两种代币(例如萝卜和白菜)的智能合约。交易者可以向交易池添加流动性,或通过池子执行买卖操作,价格则通过公式自动计算image.png

2.2 常见的 AMM 模型

image.png PancakeSwap 采用常数乘积公式: $$ x \times y = k $$ 其中:

  • (x) 和 (y) 分别代表交易池中的两种代币数量
  • (k) 是一个恒定值

该公式确保在交易前后,交易池的总价值保持不变

2.3 价格调整机制

  1. 初始设定

    • 交易池初始含有1000 单位的萝卜200 单位的白菜
    • 初始交换比率:5 萝卜 兑换 1 白菜
  2. 交易影响

    • 当用户用萝卜换白菜时:
      • 萝卜数量增加
      • 白菜数量减少
      • 自动调整交换比例
    • 例如:
      • 交易后,池子中萝卜变为 1100 单位,白菜变为 180 单位
      • 新的交换比率可能调整为:6.11 萝卜兑换 1 白菜

image.png 攻击者正是利用这一价格变动机制,通过大量买入目标代币,使其价格短时间内暴涨,进而进行套利。


3. 攻击者信息


4. 攻击流程

image.png

4.1 第一步:闪电贷借款

攻击者通过PancakeSwap 交易所借入大额资金:

  1. 第一笔借款

    • BUSD/USDT 交易池 借出 2100 USDT(即 2100 单位的白菜
    • 通过 PancakeSwap swap 函数 完成交易
  2. 第二笔借款

    • Discover/USDT 交易池 借出 19000 USDT
    • 采用回调函数,在合约内实现 嵌套调用,完成借款

image.png

🔗 交易详情:点击查看 BlockSec 交易分析


4.2 第二步:操纵市场价格

  1. 攻击者使用借来的 19000 USDT 大额购买 Discover 代币(萝卜),导致:
    • 交易池内 Discover 代币短时间内价格暴涨
    • 由于 ETHpledge 项目使用市场价格进行估值,其 Discover 代币(萝卜)估值大幅上升
  2. 攻击者利用该高估值代币进行抵押借贷
    • 攻击者在 ETHpledge 项目用 Discover 代币(萝卜)抵押
    • 获取更多的 白菜(USDT)
    • 由于市场中 Discover 价格高估,攻击者可借出的 USDT 远高于真实价值

image.png


4.3 第三步:恢复市场价格

  1. 攻击者归还部分闪电贷借款
    • 归还 2100 USDT,恢复市场流动性,使USDT 价格恢复正常
    • 但此时,攻击者已经套利获得大量 Discover 代币(萝卜) image.png

4.4 第四步:套利退出

  1. 攻击者将套利获得的 Discover 代币(萝卜)卖出,换回白菜(USDT)
  2. 归还剩余闪电贷借款,获利部分归自己

image.png

4.5 第五步:清洗资金

  1. 攻击者将获利的 USDT 兑换为 BNB
  2. 资金转入混币服务,增加追踪难度,完成攻击

三、Hardhat 靶场复现闪电贷攻击:Discover 项目

1. 攻击者准备工作

BscScan(币安区块链浏览器) 中查看到,攻击者的账户地址为:

攻击者在攻击前部署了 两个智能合约,作为整个攻击的重要组成部分:

image.png

image.png 由于攻击者不会公开智能合约源码,所以需要通过分析攻击交易来推测两个合约的功能。

2. 使用工具分析攻击交易

2.1 MetaSleuth 分析

  • 通过 MetaSleuth 工具分析攻击交易的具体执行流程。

image.png

2.2 Phalcon 分析

  • 进一步利用 Phalcon 工具查看交易的底层操作,以理解合约的交互方式。

image.png

3. 攻击合约分析

3.1 30 号合约的功能

  1. invest 函数
    • 该函数调用了 ETHplege 合约 中的 pledge 质押函数,将 Discover 代币进行抵押。

image.png

  1. 0x3e30e90f(定义为 attack 函数)
    • 该函数的主要功能是将 30 号合约中的 Discover 代币 转发给 79 号合约,供后续攻击使用。

image.png


3.2 79 号合约的功能

可以看到,整个攻击交易是由79合约中的0x77db1582函数(我们定义为attackBegin函数)发起的。attackBegin函数只调用了pancakeSwap中BUSD-BSC-USD交易池的swap函数,借出2100个BSC-USD。在pancakeSwap项目中进行闪电贷需要在自己发起闪电贷的合约中执行pancakecall函数,这是一个回调函数,用来在一笔交易中向借款的交易池还款。

  1. attackBegin 函数
    • 该函数是 整个攻击交易的入口
    • 它调用了 PancakeSwap 交易所 BUSD-BSC-USD 交易池swap 函数,借出 2100 BSC-USD(即 USDT)。

image.png

  1. pancakeCall 回调函数
    • PancakeSwap 进行闪电贷 时,调用者合约必须实现 pancakeCall 回调函数,否则交易会失败。
    • pancakeCall 在本次攻击中被 调用 2 次,且两次调用执行了不同的逻辑
    • 79 号合约内部设有 flag 变量 来区分 两次回调 的执行逻辑。

3.3 pancakeCall 两次回调逻辑

第一次回调

  • 79 号合约向 PancakeSwap: Discover-BSC-USD 交易池 再次借款,并进行代币兑换,随后完成还款。

image.png

第二次回调

  • 79 号合约执行 ETHplege 质押
  • 调用 30 号合约 中的 attack 函数,将 Discover 代币转发给 79 号合约。
  • 最后,向 PancakeSwap 归还 BSC-USD 借款

image.png

四. Hardhat 复现攻击流程

4.1 Hardhat 配置

Hardhat.config.js 中配置 Binance Smart Chain(BSC)主网:

  • 攻击发生的区块号为 18446846,需要将 Hardhat fork 到攻击发生前的区块 以进行复现。

image.png


4.2 部署攻击者的两个合约

  1. 复现攻击者部署的 30 号合约 -- 30 号合约主要用于 攻击前的资金准备,执行 invest 函数,将资金存入 ETHplege 合约

image.png -- Plegein函数的功能是质押,并且将质押人相关信息存储到ETHplege合约中。30合约还一个attack函数,用以整个攻击交易中的调用。

image.png

  1. 复现攻击者部署的 79 号合约 -- 79 号合约的构造函数获取 30 号合约的地址,确保交互逻辑匹配。

image.png 构造函数目的是拿到79合约需要交互的合约实例,方便79合约与其他合约进行调用,简化操作。

image.png --attackBegin是整个攻击交易发生的入口。该函数执行的是执行pancakeswap交易所的闪电贷功能。改swap函数需要执行调用者合约中的pancakecall的回调函数,如果没有回调函数改交易就会失败被revert。所以79合约要一个pancakecall回调函数。 之前说到pancakeCall函数在2次调用中要实现不同的的函数逻辑,所以需要通过flag来标识第几次执行pancakeCall函数的内部逻辑。 --第一次pancakeCall函数回调。

image.png --第二次pancakeCall函数回调。

image.png

至此,在智能合约上的准备和分析完成。 接下来我们需要在hardhat上去实现攻击复现。


4.3 复现攻击交易

  1. 部署合约

image.png 该函数是异步函数,传入的参数为合约名和合约构造函数需要的参数。然后将该函数模组导出,在attack-reproduction脚本中引用。

image.png 首先通过ethers拿到本地网络的用户数组,使用用户0作为攻击复现者。

image.png 然后在beforeAttack_tranferToAttack函数中进行攻击前的资金准备。调用部署函数并传入attack30 字符串参数。这样我们就能够将30合约部署上链。然后获取到部署到的attack 30 合约的地址,作为部署attack 79 合约的第二个参数。此时我们将attack30合约和attack79合约都部署上链。

  1. 调用 调用attack30.invest()和attack79.attackBegin()

image.png 目的是向ETHpeldge项目方以30合约的地址进行质押,留下30合约的信息。

image.png 79合约的attackBegin执行借款。是整个攻击交易的开始。


4.4 运行 Hardhat 复现

  1. 首先需要执行yarn hardhat node,该命令的功能是运行起hardhat本地私链。

image.png 2.然后运行以下命令:

image.png 可以在控制台窗口看到打印出的信息。

image.png

时序图如下:

image.png

五、 结语

本次 Hardhat 复现详细解析了 Discover 项目的闪电贷攻击,通过 攻击者合约的分析交易执行流程的重现,以及 时序图展示,完整还原了攻击过程。

本次复现与 KEN 共同实现,欢迎各位技术研究者批评指正。

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

0 条评论

请先 登录 后评论
SpikeDu
SpikeDu
0xf0F0...Ba88
来、来财