(分析+复现)—FEGexPRO攻击
feg 官网https://fegex.com/
1.攻击者 0x73b3 调用事先创建好的攻击合约 0x9a84 从 DVM 中闪电贷借出 915.842 WBNB,接着将其中的 116.81 WBNB 兑换成 115.65 fBNB。
漏洞分析
两个原因:
1.swaptoswap中对path的地址没有校验,将资产approve恶意的地址。
2.depositInternal中的逻辑错误。
这两个函数结合使用造成本次攻击。看起来就是一次存钱,多次取款
逐步分析
最开始调用了depositInternal
input
{
"asset": "0x87b1acce6a1958e522233a737313c086551a5c76",
"amt": "115650737205006082495"
}此时状态变量的值
此时_balances2[msg.sender]为114598114043831447113。_totalSupply2为131909646317965548044。
第一次swaptoswap
在执行swaptoswap之后
由于前面一步。所以swaptoswap中这个判断require(_balances2[msg.sender] >= amt, "Not enough Main");就是成立的。可以实现后面将fbnb approve到恶意的path中。然后子合约将钱转走。此时_balances2[msg.sender] 减去amt,变为0,_totalSupply2也减去amt,变为为17311532274134100931。回到了存钱之前的状态。但是这一波操作下来。path地址却有权限转走FEG合约中的fbnb了。
这里一切都是正常的逻辑,第二步就可以发现问题了。
第二次depositinternal
这里注意,我们给的amt参数是1。很小
运行中各个状态下的数据
一波操作之后,可以发现此时_balances2[msg.sender]为114598114043831447114。其实实际上我们传入的是amt:1。但是最后很神奇变成了114598114043831447114。这就有点离谱了。
为什么会这样,我们看看有哪些因素影响_balances2[msg.sender]的值。主要由finalAmount影响,我们仔细看上面的数值。他们的值好像和第一步存钱的时候差不多。因为在这两次操作期间,真正参与计算的_records[Main].balance和IERC20(Main).balanceOf(address(this)没有多大的变化。但是他们参与了账号余额的计算,导致把finalAmount的值改变了,所以_balances2[msg.sender] 也发生了变化。很奇妙。
第二次swaptoswap
和上面一样,由于前面的操作_balances2[msg.sender]的值符合条件,于是我们又白嫖了114598114043831447113给恶意path地址。
第三次depositinternal
状态变量的值
第三次swaptoswap
EXP
第一步,从DVM中借钱
第二步,将wbnb换成fbnb
第三步,创建子合约
第四步,漏洞利用。这里不管是exp的合约还是path的合约都定义depositInternal
exp效果,只写了dvm闪电贷的部分,从pancake借贷部分没写,实现是一样
EXP:DeFiVulhub/FEG at main · 8olidity/DeFiVulhub (github.com)
Last updated