Pickle Jar 盗币事件分析

  • A+
所属分类:安全新闻

微信又改版了,为了我们能一直相见

你的加星在看对我们非常重要

点击“长亭安全课堂”——主页右上角——设为星标🌟

期待与你的每次见面~



 前言 



2020年11月21日,Pickle Finance的PickleJar遭到攻击,损失了19.76Million Dai。2020年11月22日,Banteg 和 Pickle Finance 团队发表了该攻击构成的技术细节。本文介绍漏洞的核心原理。



 前置知识 



AMM:是一种即时兑换模式。通常的交易所(中心化/去中心化),需要买卖双方对价格达成一致,才能完成交易;而AMM 只需买方认可流通池中的Token价格即可立刻完成交易。


流动性用户将资产转入交易平台之中获得收益,而在平台中的总资产额度,就构成了流通池。流通池中代币总额越多,深度越好,大额交易带来的影响也就更小,不至于因为一笔几十万美元的交易就让价格产生大幅波动。Defi的一个风险点就是流通池不够大,容易产生较大滑点。



 漏洞介绍



Pickle Jar 的代码是Fork的Yearn Vaults v1,其中Controler v4合约用于控制其他合约,同时是用户主要调用的入口合约。Pickle Jar在原代码上增加了Jars之间的Swap功能,但该功能对targets的检查不完备,产生了漏洞。


漏洞1: 缺少外部合约地址检查,导致任意代码执行漏洞 


我们先找到Pickle Jar新增的函数swapExactJarForJar位置在Controller-v4.sol,L250


Pickle Jar 盗币事件分析


该函数用于Jar之间的转账操作,把Token从_fromJar转移到_toJar 要转移的金额为_fromJarAmount,最少到账金额为_toJarMinAmount


除此之外,我们可以看到函数还有另外两个参数_targets_data 这两个参数在L318被正式调用:


Pickle Jar 盗币事件分析


我们跟进_execute函数


Pickle Jar 盗币事件分析


可见函数的核心就是delegateCall,以此调用外部_target合约函数,input为_data 到这里,我们需要回到swapExactJarForJar函数里面,看一下_target合约地址有哪些限制。找到如下检查


require(approvedJarConverters[_targets[i]], "!converter");


可见,_target只能是approvedJarConverters白名单中的合约。


通过查看approvedJarConverters变量得知,白名单合约仅有两个:


  •  UniswapV2ProxyLogic 

  •  CurveProxyLogic


存在漏洞的是CurveProxyLogic合约,该合约用于管理流动池,因此实现了add_liquidity、remove_liquidity_one_coin两个函数。


阅读两个函数的代码,我们发现了第二处外部合约调用。


Pickle Jar 盗币事件分析


在合约的第52行,CurveProxyLogic合约调用了curve变量指向的外部合约。调用的函数名签名为curveFunctionSig,参数为liquidity和0。


可见,curve和 curveFunctionSig直接来自函数的参数,没有进行任何限制或检查。


故而,攻击者可以通过调用ControllerV4.SwapExactJarForJar函数,来以ControllerV4合约作为msg.sender执行任意外部代码。调用链图示如下:


Pickle Jar 盗币事件分析


漏洞2: 缺少对_toJar的检查,导致任意命令执行


问题同样在ControllerV4 的 swapExactJarForJar函数中, 该函数缺少对_toJar参数的检查。当执行到323行时,将会调用_toJar地址指向的外部合约的deposit函数。


Pickle Jar 盗币事件分析


攻击者可以在外部合约的deposit函数中,将_toJarToken转账到自己的钱包里。



 漏洞利用



在本次攻击事件中,攻击者的漏洞利用流程如下: 


第一步:调用earn函数


首先,攻击者调用了 pDai 的earn函数,将Jar中所有的DAI币转移给对应的Strategy 在Pickle-Finance中,DAI币对应的Strategy是strategy-cmpd-dai-v2合约 该合约在收到earn函数发过来的DAI币时,会mint等量的cDAI。


Pickle Jar 盗币事件分析


攻击者第一步攻击的简要流程图如下:


Pickle Jar 盗币事件分析


第二步:利用漏洞1


攻击者利用漏洞1来调用Strategy.withdraw函数


Pickle Jar 盗币事件分析


注意两点:

  1. Strategy 定义了两个withdraw函数,攻击者调用的是其中参数为IERC20的这个。
  2. withdraw函数对msg.sender做了检查,仅允许Controller调用该函数。这里攻击者通过controller的任意命令执行绕过了检查。在这一步中,攻击者将Strategy中所有的cDAI转移到了ControllerV4合约。


Pickle Jar 盗币事件分析


第三步:利用漏洞2


接着,攻击者利用漏洞2,将Controller中的所有cDAI转移到自己钱包中。


Pickle Jar 盗币事件分析


最后,得到所有cDAI的攻击者来到Compound,将手中的cDAI凭证换为真正的DAI币。至此,整个攻击流程结束。



 修复措施



北京时间2020年11月22日,上午11:58,PickleJar关闭了deposit函数。


北京时间 2020年11月22日,下午15:16,Pickle Jar 团队调用了Controller-v4的revokeJarConverter管理函数,从白名单中删除了CurveProxyLogic合约。


虽然从白名单中删除了漏洞合约,使漏洞无法被利用。但是CurveProxyLogic合约中的漏洞依然存在,Pickle Jar团队还在进行进一步修复



 总结



Pickle Jar的子合约CurveProxyLogic中调用了call函数,同时没有检查外部合约地址。这使得攻击者可以执行任意代码,篡改合约的状态。作为合约的开发人员,需要谨慎使用delegatecall和call函数,严格限制这两个函数的参数。


另一方面,合约项目方可以通过赏金计划、漏洞平台等方式吸引社区中的白帽黑客来发现项目中的安全漏洞,帮助项目的完善和安全性提升。最后,项目方可以联系国内有区块链合约安全相关服务的厂家(比如长亭科技)来支持代码审计工作。



 引用



  • Pickle Team官方声明 

  • yearn.finance核心开发banteg的事件分析 

  • 攻击者的全部交易 transactions tree 

  • pickle finanace 合约代码 

  • 长亭科技 Chaitin


Pickle Jar 盗币事件分析
点分享
Pickle Jar 盗币事件分析
点点赞
Pickle Jar 盗币事件分析
点在看


本文始发于微信公众号(长亭安全课堂):Pickle Jar 盗币事件分析

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: