前言
北京时间 2022 年 3 月 31 日,知道创宇区块链安全实验室 监测到借贷平台 Ola_finance 遭到重入攻击,黑客窃取 216964.18 USDC、507216.68 BUSD、200000.00 fUSD、55045 WETH、2625 WBTC 和 1240,000.00 FUSE,约 467 万 美元。
分析
其中一起攻击事件如下图所示,该次攻击事件的问题点在于 Ola.finance 和 ERC677 代币的不兼容,这些代币的内置回调函数被攻击者利用进行重入攻击以耗尽借贷池。
所有攻击事件如下:
20 WBTC + 100 WETH 被盗:https://explorer.fuse.io/tx/0xe800f55fe6c81baba1151245ebc43692735d4019107f1f96eeb9f05648c79938/token-transfers
100 WETH 被盗:https://explorer.fuse.io/tx/0xb8ef2744647027047e383b6cdd660a950b4f6c6bbbc96378ef1e359b4369ffc1/token-transfers
100 WETH 被盗:https://explorer.fuse.io/tx/0xff4fa726d0967bda03124fb71d58f0aa32d8132029804cdcf0c517761f4acd74/token-transfers
100 WETH 被盗:https://explorer.fuse.io/tx/0xf06a9b830dc2577e62016df45ee6f824d9112d32d3f66f4e1e31639d15a3812d/token-transfers
100 WETH 被盗:https://explorer.fuse.io/tx/0xb535823c71bf753e6468e40ce009f00ab473e716900417719377a0c50892816f/token-transfers
52.094 WETH 被盗:https://explorer.fuse.io/tx/0xf1ac951de9eda1be73fd99adf9cca902b0ff28515ec3061b487e52cf352f5b6a/token-transfers
6.246 WBTC 被盗:https://explorer.fuse.io/tx/0x719ec16e785463adf78e8ebf32286f837f7546e4301d9bce620da08af435bb3a/token-transfers
216964.176 USDC 被盗:https://explorer.fuse.io/tx/0x0df8dce11993a2efff59a416aa967b64b9ebe0ab66f996cfdb41a463b952dd86/token-transfers
507216.676 BUSD 被盗:https://explorer.fuse.io/tx/0x1b3e06b6b310886dfd90a5df8ddbaf515750eda7126cf5f69874e92761b1dc90/token-transfers
200000 fUSD 被盗(借入后抵押品被盗):https://explorer.fuse.io/tx/0x17883e8a1bcfc85b80f00f8faa730f2da17b1d9fe48c1922c05e51a1a9e01a2c/token-transfers
1240000 FUSE 被盗(借入后抵押品被盗):https://explorer.fuse.io/tx/0x8223170a722eba6d4583845f377ba5f353e8e589d0d16b6a4fb0a2feaad94a8c/internal-transactions
基础信息
攻击合约:
Contract1:0x632942c9BeF1a1127353E1b99e817651e2390CFF
Contract2:0x9E5b7da68e2aE8aB1835428E6E0c83a7153f6112
攻击者地址: 0x371D7C9e4464576D45f11b27Cf88578983D63d75
攻击 tx: 0x1b3e06b6b310886dfd90a5df8ddbaf515750eda7126cf5f69874e92761b1dc90
漏洞合约: 0x139Eb08579eec664d461f0B754c1F8B569044611
流程
攻击者攻击的流程如下:
1.攻击者将 550.446 WETH 从攻击合约 0x6392 转到另一个攻击合约 0x9E5b。
2.攻击者存入 550.446 WETH 到 cETH 合约 0x139Eb08579eec664d461f0B754c1F8B569044611 获取铸币 27284.948 oWETH。
3.由于有了 27284.948 oWETH,攻击者可以从 cBUSD 合约 0xBaAFD1F5e3846C67465FCbb536a52D5d8f484Abc 中借出 507216.676 BUSD。
4.攻击者在 BUSD 转账到攻击合约 0x9E5b 期间调用回调函数,将 27284.948 oWETH 转给 攻击合约 0x6329,借到 507216.676 BUSD 后也转给攻击合约 0x6329。
5.攻击合约 0x6329 赎回 27284.948 oWETH 获得 550.446 WETH。
细节
该攻击事件主要问题发生在上面流程的第三步和第四步。
由于 ERC677 代币中存在 transferAndCall 函数,所以可以进行外部调用(详情可以查看 https://explorer.fuse.io/address/0x5De15b5543c178C111915d6B8ae929Af01a8cC58/contracts )。
16487976226614.jpg 在 BUSD 从 oBUSD 借出转账到攻击合约 0x9E5b 期间,在攻击合约 0x9E5b 中调用一个回调函数,将 oWETH 从 攻击合约 0x9E5b 转到 攻击合约 0x6329 中(此时攻击合约 0x9E5b 的借贷余额还未更新),借出 BUSD 后也转给攻击合约 0x6329。
通过代码我们可以看出虽然 Erc20Delegator 合约的 函数有防止重入修饰器 的限制,但这个修饰器只能防止外部调用重入攻击自身合约,并不能够防止外部调用重入其他合约。
最后由于攻击合约 0x6329 没有进行借贷,所以它可以将 oWETH 赎回 WETH。攻击者最终得到了用作抵押来借用 BUSD 代币的 WETH 和他们借来的 BUSD 代币。
后续处理
Ola.finance 官方发表声明称:
我们将发布一份关于所有借贷网络中列出的所有代币的详细报告,确认此攻击无法在其他借贷网络上复制。为此,我们将调查每个代币的「转移」逻辑,以确保没有使用有问题的代币标准。此外,每个借贷网络创建者都将被提供在其借贷网络上快速暂停代币铸造和借贷的能力。 稍后,我们将发布一个补丁,允许 Compound 分叉安全地列出符合 ERC677/ERC777 标准的代币。在此之前,Fuse 上的借贷网络的借贷将暂时禁用;借入资产的用户不会累积利息,并鼓励他们此时不要偿还贷款(因为他们不太可能提取抵押品)。一旦此补丁经过彻底测试和审核,Voltage 上的全部借贷功能将恢复。 在接下来的几天里,我们将发布正式的补偿计划,详细说明向受影响用户分配的资金。这将伴随更多文章,概述我们将更深入地采取的「下一步」。我们感谢我们的合作伙伴支持分析这次攻击并帮助我们迅速解决问题。
总结
Ola.finance 是基于 Compound 合约改写的,而 Compound 合约和 ERC677/ERC777 的代币之间不兼容,使得这些代币的内置回调函数被攻击者利用,用以重入来耗尽借贷池。