PeckShield:DeFi平台Opyn智能合约漏洞详解——攻击者空手套白狼!
北京时间2020年08月05日,DeFi 期权平台 Opyn 的看跌期权(Opyn ETH Put)智能合约遭到黑客攻击,损失约37万美元。
Opyn 是一个通用期权协议,于今年2月份转型为保险平台,通过 oTokens 为 DeFi 平台提供可交易的 ETH 看跌期权,以此锚定 ETH 市场价格,为高波动性的 DeFi 市场提供相对的稳定性。
PeckShield 安全团队获悉 Opyn 平台遭受攻击后,迅速定位到问题关键点在于:
攻击者发现 Opyn 智能合约行权(exercise)接口对接收到的 ETH 存在某些处理缺陷,其合约并没有对交易者的实时交易额进行检验,使得攻击者可以在一笔对自己发起真实的交易之后,再插入一笔伪装交易骗得卖方所抵押的数字资产,进而实现空手套白狼。
简单来说,由于 Opyn ETH Put 智能合约中的行权函数 exercise() 没有对交易者的ETH 进行实时校验。根据 Opyn 平台的业务逻辑,看跌期权的买方给卖方转移相应价值的 ETH,即可获得卖方抵押的数字资产。狡猾的攻击者,先向自己发起伪装的交易,利用这笔 ETH 可以重复使用的特性,再次向卖方用户发起转账,进而骗取卖方已经抵押的数字资产。
下面为您详细分析漏洞原因及攻击过程。
、
漏洞详细过程分析
先来说说,Opyn 平台的业务逻辑:当用户使用 Opyn 合约行权即买卖期货(exercise)时,需要买方向卖方转入相应数量的 ETH 或者 ERC20 Token,然后合约将销毁买方对应的 oToken,而后买方将获得卖方已经抵押的资产。
例如:小王认为行情进入了下跌趋势,看到 Opyn 上挂着一个小李对 ETH 330美元的看跌期权,于是进入交易系统,向小李转账一个 ETH,获得小李抵押的等额数字资产。若此刻行情已经跌至了300美元,小王便可获得其中的差价。
图1. exercise() 函数中循环执行传入的 vaults 地址列表
如上面的合约代码片段所示,行权函数 exercise() 的内部是一个循环,依据参数中传递的 vaultsToExerciseFrom 中的地址数量依次调用真正的行权逻辑 _exercise() 函数。
图2. 重用传入合约的 ETH 来获得抵押资产
函数处理 ERC20 Token 时,和大部分的 DeFi 项目做法一样,使用 transferFrom(),如代码 1882 行所示,从 msg.sender 转账到 address(this)。
但是当函数处理的资产为 ETH 时,处理的方式就完全不一样了。因为在 Solidity 中,msg.value 的意思是合约调用者在调用具有 payable 接口时所转给该合约的 ETH 数量,仅是一个量值,所以在合约代码的 1879 行中,检查 msg.value == amtUnderlyingToPay 仅能确保合约确实收到了 amtUnderlyingToPay 数量的 ETH,并不会对 msg.value 的值造成任何影响。
但是正如上面讲到的在 exercise() 中会循环调用 _exercise() 函数,这导致尽管合约实际只收到一次ETH,然而在循环过程中却可以重复使用。
攻击点就在这里,由于合约少了一步对 ETH 实时数量的检验,使得攻击者可以先伪造一笔指向自己的交易,然后再把已经花掉的本金再次利用,和平台其他用户完成一笔正常交易。
图3. 攻击交易分析
在图3中,我们通过 Bloxy 浏览器显示的调用过程来展示攻击的过程。由于攻击者吃掉了很多笔订单,我们以其中一笔交易为例,向大家展示其攻击逻辑:
1、攻击者先从 Uniswap 购入了 75 oETH 为进一步调用函数行权做好筹备;
2、攻击者创建了一个 Vault 地址,作为看空期权卖方,并且抵押24,750 USDC 铸造出75 oETH,但并未卖出这些期权,等于自己同时买入了以 330 的价格卖出75 ETH 的权利;
3、攻击者在 Opyn 合约中调用了 exercise(),在持有 150 oETH 看空期权的情况下,先向自己的 Vault 地址转入了75个 ETH,获得自己事先抵押的 24,750 个 USDC,再重利用了这75个 ETH,成功吃掉了另一个用户的 24,750 个 USDC,进而实现非法获利。
修复建议
PeckShield 安全团队建议,在 Solidity 中,合约可使用一个局部变量 msgValue 来保存所收到 ETH(即 msg.value 的值)。这样,在后续的步骤中通过操作 msgValue ,就能准确的标记有多少 ETH 已经被花费,进而避免资产被重复利用。此外,我们还可以使用 address(this).balance 来检查合约余额来规避 msg.value 被重复使用的风险。
PeckShield 作为业内领先的区块链安全公司,安全业务已覆盖全球范围,主要客户包括有:公链提供商 (EOS、Nervos、Harmony、AVA、HBTC、NEO 、IOST、Bytom、TRON、OKChain),头部钱包和矿池 (imToken、SparkPool、比特派、Cobo 金库,VoiceWallet),以及头部交易所(Huobi、KuCoin、Bithumb、Upbit、OKex)、DeFi 应用及智能合约(MakerDAO、StarkWare、bZx、Aave、Tokenlon、InstaDApp、Set Protocol、Zerion、Ren Project、Hydro Protocol、dForce、Newdex、HoneyLemon)等。
近一年内,PeckShield 已经接连审计了数十个 DeFi 项目,帮助 DeFi 协议做代码安全审计、业务逻辑风控、威胁情报风险预警等等,已经成为服务 DeFi 领域的头部安全公司。
推荐阅读:
PeckShield:硬核技术解析,bZx协议遭黑客漏洞攻击始末
PeckShield:bZx协议再遭黑客“二连击”背后的技术命门
0x协议漏洞原理剖析:恶意挂单可扰乱正常交易秩序
Uniswap和Lendf.Me遭攻击始末:DeFi乐高组合下的“多米诺”式崩塌
AirSwap智能合约漏洞详解:用户资产可被攻击者恶意吃单?
PeckShield:DeFi平台Opyn智能合约漏洞详解——攻击者空手套白狼!相关推荐
- 以太坊智能合约ABI详解
在以太坊生态系统中, ABI 是从区块链外部与合约进行交互以及合约与合约间进行交互的一种标准方式.本文让我们了解一下智能合约的 ABI 是什么. ABI是什么 在计算机科学中,ABI(应用程序二进制接 ...
- fabric 智能合约开发详解
一.fabric 智能合约运行环境 Chaincode是一个程序, Chaincode运行在一个被背书peer进程独立出来的安全的Docker容器中,Fabric中支持多种语言实现链码,包括golan ...
- 这些智能合约漏洞,可能会影响你的账户安全!
摘要:区块链联盟链智能合约形式化验证揭秘,解释了我们为什么要对区块链上的智能合约进行形式化验证,以及形式化验证的分类和业界针对每种分类所推出的形式化验证工具,最后作者描述了一下目前形式化验证的种种方法 ...
- 智能合约漏洞攻击事件_智能合约百科全书攻击漏洞
智能合约漏洞攻击事件 Applications on Ethereum manage financial value, making security absolutely crucial. As a ...
- 基于GNN的智能合约漏洞检测(tmp)方法部分翻译(1)
背景 实在是没办法,不翻译印象不深... 我们的方法 为了解决现有工具在智能合约检测方面的不足,我们提出了一种超出传统基于规则的框架的方法.特别地,我们根据程序中的数据流和控制流关系将智能合约源代码提 ...
- OWASP-TOP10漏洞详解以及防护方案
OWASP TOP 10 漏洞详解以及防护方案 OWASP介绍 官网:http://www.owasp.org.cn/ OWASP TOP10 指出了 WEB 应用面临最大风险的 10 类问题,是目前 ...
- Pikachu靶场之文件包含漏洞详解
Pikachu靶场之文件包含漏洞详解 前言 文件包含漏洞简述 1.漏洞描述 2.漏洞原因 3.漏洞危害 4.如何防御 第一关 File Inclusion(local) 1.尝试读取"隐藏& ...
- Pikachu靶场之越权漏洞详解
Pikachu靶场之越权漏洞详解 前言 逻辑越权漏洞简述 漏洞描述 漏洞原因 漏洞分类 水平越权 垂直越权 权限框架缺陷 如何防御 第一关 水平越权 问题分析 尝试防御 第二关 垂直越权 问题分析 尝 ...
- XSS(跨站脚本)漏洞详解之XSS跨站脚本攻击漏洞的解决
XSS(跨站脚本)漏洞详解 XSS的原理和分类 跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆, ...
最新文章
- tensorflow model.compile() 示例
- 二叉树的先序建树后序输出
- WinHand.cpp Line 199 错误 WinHand.cpp Line 218 错误
- mysql blob取值_MySQL 数据类型:
- 【Android】11.3 屏幕旋转和场景变换过程中GridView的呈现
- 2018-2019-1 20165221 《信息安全系统设计基础》第一周学习总结
- 【Ansible】Ansible控制windows插件安装及运行error与解决方法
- 线性表:顺序队列算法实现
- java基础—Runtime类使用
- Uploadify 配置错误信息提示
- 第 17 章 命令模式
- 关于PyCharm卡顿的问题
- vscode的pip安装
- html以鼠标为中心放大网页,鼠标滚轮网页放大缩小
- 系统分析设计——如何识别类
- 实现 RecyclerView 上拉加载及自动加载
- 分布式事务方案Seata
- ESLint 报 ‘require‘ is not defined no-undef
- c++基础题:判断奇偶数
- 64个数据分析常用术语