背景介绍

2024 年 7 月 12 日,DoughFina 协议遭受了黑客攻击,造成本次攻击的主要原因是 ConnectorDeleverageParaswap 合约没有对输入参数进行检查,且该合约为 DSA 合约的 owner。攻击者可以构造恶意参数窃取 DSA 合约的资金。

攻击交易

https://app.blocksec.com/explorer/tx/eth/0x92cdcc732eebf47200ea56123716e337f6ef7d5ad714a2295794fdc6031ebb2e

相关合约

  • DSA(被攻击地址):0x534a

    在 AAVE V3 上质押了 596 WETH,借出了 938566 USDC
  • 攻击合约:0x11a8
  • ConnectorDeleverageParaswap:0x9f54e8eaa9658316bb8006e03fff1cb191aafbe6

    通过闪电贷协助 DSA 降低在 AAVE V3 上的杠杆。

攻击交易分析

这个章节我们先尝试从 trace 来定位漏洞的位置。

通过对这笔交易进行一个大概的观察,如下图所示,攻击者在发起攻击之前,先利用闪电贷的资金帮 0x534a 归还了他的借款 938566 USDC,其他部分都是常规的操作,其中需要深入调查的就是 0x11a8 调用 ConnectorDeleverageParaswap.flashloanReq 函数的过程。

ConnectorDeleverageParaswap.flashloanReq 函数

我们看到在 ConnectorDeleverageParaswap.flashloanReq 函数中,会调用 POOL.flashLoan

POOL.flashLoan 执行一个常规的闪电贷流程

  1. ConnectorDeleverageParaswap 合约从闪电贷获取 5 USDC
  2. 调用 ConnectorDeleverageParaswap.executeOperation 函数
  3. 归还 5.025 USDC
  4. handleRepayment

继续跟进到 ConnectorDeleverageParaswap.executeOperation 函数,可以看到它对传入的参数进行解析后直接调用 deloopInOneOrMultipleTransactions 函数

deloopInOneOrMultipleTransactions 函数进行分析

function deloopInOneOrMultipleTransactions(bool opt, address _dsaAddress, address[] memory assets, uint256[] memory amounts, uint256[] memory premiums, address[] memory collateralTokens, uint256[] memory collateralAmounts, bytes[] memory multiTokenSwapData) private {
// Repay all flashloan assets or withdraw all collaterals
// 使用闪电贷获得的资金来偿还用户在 Aave 上的债务。
repayAllDebtAssetsWithFlashLoan(opt, _dsaAddress, assets, amounts); // Extract all collaterals
// 从用户的 DSA 中提取指定数量的抵押品。
extractAllCollaterals(_dsaAddress, collateralTokens, collateralAmounts); // Deloop all collaterals
// 使用 Paraswap 将提取的抵押品换成债务代币
deloopAllCollaterals(multiTokenSwapData); // Repay all flashloan assets or withdraw all collaterals
// 偿还闪电贷,然后将剩余的资金存回 Aave 或转移到金库
repayFlashloansAndTransferToTreasury(opt, _dsaAddress, assets, amounts, premiums);
}

不过在查看 ConnectorDeleverageParaswap.executeOperation 函数的执行 trace 时,发现 Phalcon 把调用的四个函数混在一起了不好分辨。

根据转移的金额确定攻击发生的位置,猜测这笔 WETH 的转账与漏洞的利用有关。

所以通过单步调试的方式来检查发生了什么。

执行到 ConnectorDeleverageParaswap.deloopAllCollaterals 函数中时,对传入的 multiTokenSwapData 参数进行解析,得到对应的参数: flashloanVars.srcToken, flashloanVars.destToken, flashloanVars.srcAmount, flashloanVars.destAmount, flashloanVars.paraSwapContract, flashloanVars.tokenTransferProxy, flashloanVars.paraswapCallData

其中 paraSwapContract(out4)对应的地址为 WETH 的合约地址(0xc02a),而不是进行 swap 的合约地址。

当执行到 paraSwapContract.call 部分的函数时,由于 paraSwapContract 的地址已被替换为 WETH9 的地址,且 paraswapCallData 为攻击者构造的转账 calldata,所以实际执行的是 WETH 的转账操作

function deloopAllCollaterals(bytes[] memory multiTokenSwapData) private {
FlashloanVars memory flashloanVars; for (uint i = 0; i < multiTokenSwapData.length;) {
// Deloop
(flashloanVars.srcToken, flashloanVars.destToken, flashloanVars.srcAmount, flashloanVars.destAmount, flashloanVars.paraSwapContract, flashloanVars.tokenTransferProxy, flashloanVars.paraswapCallData) = _getParaswapData(multiTokenSwapData[i]); // using ParaSwap
IERC20(flashloanVars.srcToken).safeIncreaseAllowance(flashloanVars.tokenTransferProxy, flashloanVars.srcAmount);
(flashloanVars.sent, ) = flashloanVars.paraSwapContract.call(flashloanVars.paraswapCallData);
if (!flashloanVars.sent) revert CustomError("ParaSwap deloop failed"); unchecked { i++; }
}
}

deloopInOneOrMultipleTransactions 函数分析

已经定位到了漏洞发生的位置,接下来就根据 trace 分析 deloopInOneOrMultipleTransactions 函数对四个函数的调用情况

  1. repayAllDebtAssetsWithFlashLoan

    替 0x11a8 账户归还 5 USDC 的借款

  2. extractAllCollaterals

    传入空数组,跳过这函数的逻辑

  3. deloopAllCollaterals

    由于没有进行参数检查,攻击者在这个函数中构造了两个恶意的调用来获利。

    1. 第一个 for 循环:调用 0x534a.executeAction 把 5 USDC 兑换成 596 WETH,并且 approve 给 ConnectorDeleverageParaswap 合约

    2. 第二个 for 循环:把 596 WETH 转移到攻击者控制的 0x11a8 地址

  4. repayFlashloansAndTransferToTreasury

    提供 0.9 USDC 给 0x11a8 的 AAVE 账户

攻击流程分析

本次攻击是围绕降低 0x11a8 账户在 AAVE V3 上的杠杆而展开的,由于这个函数没有对传入的参数进行检查,所以攻击者构造了恶意的 multiTokenSwapData 参数在 deloopAllCollaterals 函数中对 0x534a 的 AVVE 资金进行转移。

攻击者构造恶意的 data 参数,解析出恶意的 multiTokenSwapData 参数

恶意的 multiTokenSwapData 参数传入到 deloopAllCollaterals 函数中

恶意的 multiTokenSwapData 参数解析出恶意的 paraSwapContractparaswapCallData,导致了任意执行。

后记

第一次分析这个类型的攻击事件,感觉攻击事件还是得多分析,多积累积累经验,扩展自己的视野。好好看好好学吧,之前对项目类型的接触和理解上都有很大的局限,还是需要多接触一下目前经典的、热门的项目有利于提高自己的水平,跟上市场的步伐。继续干呗,这事儿只能靠慢慢积累起来的。

【漏洞分析】DoughFina 攻击事件分析:不做任何参数检查的去杠杆合约的更多相关文章

  1. 孟加拉央行SWIFT攻击事件恶意木马分析(转)

    第一章 分析概述 该恶意木马样本为运行于winodws平台上的PE文件(名称:evtdiag.exe).文件大小为64KB,编译时间是2016年2月5日. 经分析,该样本为定制的攻击SWIFT客户端程 ...

  2. 【漏洞复现】Paraluni 安全事件分析及复现

    Paraluni 被黑分析 前言 Paraluni (平行宇宙)是新加坡 Parallel Universe 基金会发布的一个 基于币安智能链的 DeFi 项目,更多相关内容见此处.在 2022 年 ...

  3. 【漏洞分析】KaoyaSwap 安全事件分析

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

  4. Log4shell漏洞研究及其挖矿案例分析

    本文首发于云影实验室,为本人创作,现转载到个人博客,记录一下. 原文链接:https://mp.weixin.qq.com/s/O2xHr2OEHiga-qTnbWTxQg Apache Log4j是 ...

  5. ENode框架Conference案例分析系列之 - 事件溯源如何处理重构问题

    前言 本文可能对大多数不太了解ENode的朋友来说,理解起来比较费劲,这篇文章主要讲思路,而不是一上来就讲结果.我写文章,总是希望能把自己的思考过程尽量能表达出来,能让大家知道每一个设计背后的思考的东 ...

  6. 从源码的角度分析ViewGruop的事件分发

    从源码的角度分析ViewGruop的事件分发. 首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View ...

  7. OneAlert 入门(三)——事件分析

    OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...

  8. 再谈DOMContentLoaded与渲染阻塞—分析html页面事件与资源加载

    浏览器的多线程中,有的线程负责加载资源,有的线程负责执行脚本,有的线程负责渲染界面,有的线程负责轮询.监听用户事件. 这些线程,根据浏览器自身特点以及web标准等等,有的会被浏览器特意的阻塞.两个很明 ...

  9. [Abp 源码分析]九、事件总线

    0.简介 事件总线就是订阅/发布模式的一种实现,本质上事件总线的存在是为了降低耦合而存在的. 从上图可以看到事件由发布者发布到事件总线处理器当中,然后经由事件总线处理器调用订阅者的处理方法,而发布者和 ...

  10. 007_ip统计及攻击ip分析

    线上经常有被扫描的DDoS攻击事件,需要集合日志进行分析,这里有两种方法,分别是通过shell和python的方式. 一.shell '''<1>shell一句命令分析 http://bl ...

随机推荐

  1. 移动通信网络中的 GTP 协议

    目录 文章目录 目录 GTP GTP-C 协议(GTP 控制面) GTP-U 协议(GTP 用户面) GTP' 协议(计费传输) GTPv2 Header GTP GTP(GPRS Tunnellin ...

  2. PageOffice在线打开 word 文件,并且禁止复制

    在线打开 word 禁用拷贝的三种方式: 1 使用 AllowCopy 属性,效果:所有的 word 进程都不能进行拷贝操作 2 禁止 word 选择功能,效果:因为无法选择,所以无法拷贝 3 使用 ...

  3. PageOffice实现文件在线安全预览——禁止编辑、下载、复制等

    实际应用中,很多时候不仅需要在线编辑文件,还需要在线安全预览文件,要求不能复制.下载.另存到本地等情况.pageoffice可以实现文件在线安全预览,禁止:编辑.复制.粘贴.右键菜单.选择.下载.另存 ...

  4. GeminiDB PITR,让游戏回档“进退自如”!

    本文分享自华为云社区<GeminiDB PITR,让游戏回档"进退自如"!>,作者:GaussDB 数据库. 在实际业务场景中,客户数据库难免会出现数据损毁.数据丢失. ...

  5. Vue History模式IIS的配置补充

    摘自 :https://blog.csdn.net/ssdnif/article/details/103856283 官方提供的配置<?xml version="1.0" e ...

  6. win11或win10客户端邮箱账号登录设置

    1.alimall阿里企业邮箱 点击账户 点击添加账户 点击其他账户 输入电子邮箱地址和密码,并点击登录即可 2.Qq邮箱 2.1 点击账户 2.2 点击添加账户 2.3 点击其他账户 2.4 输入电 ...

  7. Django模型层Models的使用步骤

    1.安装pymysql(这里使用MySQL数据库) pip install pymysql 2.在Django的工程同名子目录的__init__.py文件中添加如下语句 from pymysql im ...

  8. Linux之命令提示符的颜色设置

    1.临时设置 执行下面的命令: export PS1="[\[\e[34;1m\]\u@\[\e[0m\]\[\e[32;1m\]\H\[\e[0m\] \[\e[31;1m\]\w\[\e ...

  9. C++笔记(13)数组的引用和引用的数组

    数组的引用 数组有二个特性,影响作用在数组上的函数:一是不能复制数组,二是使用数组名时, 数组名会自动指向其第一个元素的指针. 因为不能复制,所以无法编写使用数组类型的形参,数组会自动转化为指针.比如 ...

  10. k8s集群创建阿里云版本

    阿里云创建k8s集群实例 创建两个8G内存的抢占实例(青岛),能ssh 默认关闭防火墙,且没有交换分区 配置/etc/hosts,主机名 配置k8s仓库 配置命令补全 安装docker(需要conta ...