(分析+复现)—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_totalSupply2131909646317965548044

第一次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].balanceIERC20(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