Jarvis Network闪电贷重入攻击事件分析

区块链安全 2年前 (2023) admin
409 0 0

根据NUMEN链上监控显示,Jan-15-2023 05:43:37 PM +UTC时间,Jarvis Network项目遭到攻击,损失663101个MATIC。
具体tx如下:
https://polygonscan.com/tx/0x0053490215baf541362fc78be0de98e3147f40223238d5b12512b3e26c0a2c2f

Jarvis Network闪电贷重入攻击事件分析

根据调用栈分析,交易中涉及到很多代币转账,所以调用栈很长,我们分析发现在调用过程中存在重入的逻辑。在重入的过程中发现重入前和重入后,对同一个合约的同一个函数调用,传入参数也一样,但是返回值差别很大。 
重入前:1002157321772769944
重入后:10091002696492234934

Jarvis Network闪电贷重入攻击事件分析

重入发生在remove_liquidity,这个函数在(https://polygonscan.com/address/0xfb6fe7802ba9290ef8b00ca16af4bc26eb663a28#code)这个合约中。remove_liquidity这个函数在移除流动性的时候会把用户添加的代币返回给用户,由于polygon和evm是同构链,所以在matic转账给合约的时候会进入到合约的重入。详细分析调用栈中重入的部分。

Jarvis Network闪电贷重入攻击事件分析

首先看getUnderlyingPrice(https://polygonscan.com/address/0xcc6aa628516bb46391b05b16e5058c877461cc76#code)上面是逻辑合约,但是不开源。

Jarvis Network闪电贷重入攻击事件分析

Jarvis Network闪电贷重入攻击事件分析

根据插槽得到v1=0xe7cea2f6d7b120174bf3a9bc98efaf1ff72c997d,wtoken=0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270。所以进入if分支,然后通过插槽查到_oracles[v1]=0xacf3e1c6f2d6ff12b8aee44413d6834774b3f7a3,继续进入里面的else分支后调用0xacf3e1c6f2d6ff12b8aee44413d6834774b3f7a3合约的getUnderlyingPrice函数。0xacf3e1c6f2d6ff12b8aee44413d6834774b3f7a3对应的逻辑合约是0x3803527dcd92ac3e72a0a164db82734daba47fac,这个合约也没有开源

Jarvis Network闪电贷重入攻击事件分析

Jarvis Network闪电贷重入攻击事件分析

这个是一些内置的计算,因为攻击涉及到重入,考虑到一定是重入前和重入后的一些变量是转账发生之后计算的,这部分代码不涉及到外部变量,所以问题应该不在这。除此之外还调用了0x9de。

Jarvis Network闪电贷重入攻击事件分析

varg0是传入的代币地址,也就是0xe7cea2f6d7b120174bf3a9bc98efaf1ff72c997d。对应的_poolOf[v0]是0xfb6fe7802ba9290ef8b00ca16af4bc26eb663a28。进入这个合约分析get_virtual_price函数。对应代码如下:

Jarvis Network闪电贷重入攻击事件分析

self.token还是0xe7cea2f6d7b120174bf3a9bc98efaf1ff72c997d,除数是这个代币的总发行量

Jarvis Network闪电贷重入攻击事件分析

看到D会影响get_xcp的返回。因为重入发生在remove_liquidity,所以分析remove_liquidity函数。详细代码如下:

Jarvis Network闪电贷重入攻击事件分析

调用前后get_virtual_price返回值变化。

Jarvis Network闪电贷重入攻击事件分析

Jarvis Network闪电贷重入攻击事件分析

self.D的更改在转账之后。攻击者在移除流动性的时候,matic转移到攻击者合约,回调fallback时候先查了一下0xe7cea2f6d7b120174bf3a9bc98efaf1ff72c997d价格,由于self.D更新在转账之后,所以导致之前的价格获取错误。

移除流动性方法流程:1)销毁用户LP;2)发送给用户质押资金;3)更新self.D。 

self.D用于价格计算,添加流动性时也对self.D更新,并且攻击者此次流动性资金较大。根据self.D计算公式self.D = D – D * amount / total_supply,amount和total_supply近乎相等,正常计算时,self.D值会小很多。 

但由于攻击者在2)进行了重入,并且比原始价格增高了10倍进行借贷,正是因为self.D值在添加流动性时增大,而移除流动性时未及时更新。 

这里remove_liquidity 移除流动性方法虽然添加了@nonreentrant(‘lock’)来防止重入该方法,但由于攻击者重入进入其他合约借贷资金,这里重入锁并不能奏效。

总结:

本次攻击主要是因为变量修改逻辑在外部调用之后,导致价格获取出现异常,并且跨合约重入使得重入锁不能奏效,NUMEN实验室提醒项目方代码要经过严格的安全审计,变量修改要放在外部调用之前并且价格获取采用多数据源的方式,代码逻辑遵循先判断,后写入变量,再进行外部调用的编码规范(Checks-Effects-Interactions)会使项目更加安全稳定。NUMEN拥有专业的安全团队,为WEB3生态保驾护航

Jarvis Network闪电贷重入攻击事件分析

Numen 官网
https://numencyber.com/ 
GitHub
https://github.com/NumenCyber
Twitter
https://twitter.com/@numencyber
Medium
https://medium.com/@numencyberlabs
LinkedIn
https://www.linkedin.com/company/numencyber/

原文始发于微信公众号(Numen Cyber Labs):Jarvis Network闪电贷重入攻击事件分析

版权声明:admin 发表于 2023年1月17日 上午10:02。
转载请注明:Jarvis Network闪电贷重入攻击事件分析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...