header-langage
简体中文
繁體中文
English
Tiếng Việt
Scan to Download the APP
Partnered With:

Slow fog: DeFi platform lendf.me is hacked for detailed analysis and defense advice

Read this article in 13 Minutes
Hackers continue to convert stolen COINS into ETH and other tokens through DEX platforms such as 1inch.exchange, ParaSwap, Tokenlon, etc.

BlockBeats: early morning, April 20th; & have spent The dForce Network issued an official statement saying that the attack was mainly a re-entry attack using the vulnerability of the imBTC asset ERC777 standard. The call-back mechanism allowed the hackers to repeatedly lend fake imBTC as collateral, resulting in about $25m worth of assets being taken out of contracts. As shown in the"DForce Yang min dao: cooperating with trading platform, public security, and communicating with hackers to recover stolen money".


Text title: slow fog: DeFi platform lendf.me blackened details analysis and defense Suggestions
Slow fog technology


preface


According to slow fog intelligence, the ethereum DeFi platform lendf.me has been attacked by a re-entry vulnerability. The slow fog security team immediately analyzed the attack after receiving the intelligence and quickly located the problem.


According to the preliminary statistical analysis of slow fog technology anti-money laundering (AML) system, the cumulative loss of lendf.me under attack is about $24,696,616, and the specific stolen currency and amount are:

WETH: 55159.02134.
WBTC: 9.01152.
CHAI: 77930.93433.
HBTC: 320.27714.
HUSD: 432162.90569.
BUSD: 480787.88767.
PAX: 587014.60367,
TUSD: 459794.38763.
USDC: 698916.40348.
USDT: 7180525.08156.
USDx: 510868.16067.
ImBTC: 291.3471


After that, the attackers repeatedly exchanged the stolen COINS into ETH and other tokens through DEX platforms such as 1inch.exchange, ParaSwap, Tokenlon, etc.


The following is a detailed analysis of the process.

Attack the details


This to Lendf. Me to carry out attacks of the attacker address 0 xa9bf70a420d364e923c74448d9d817d3f2a77822, 0 x538359785a8d5ab1a741a0ba94f26a800759d91d attacker by deploying contracts to Lendf. To attack Me.

Through the view of the attacker in Etherscan one deal: https://etherscan.io/tx/0xae7d664bdfcc54220df4f18d339005c6faf6e62c9ca79c56387bc0389274363b



We found that the attacker first deposited 0.00021593 imBTC, but successfully withdrew 0.00043188 imBTC from lendf.me, which was almost double the amount of imBTC deposited. So how did the attacker double the balance from a single transaction? This requires us to analyze each and every move in the trade to see what is really going on.

By looking at the transaction on bloxy.info, we can see the full flow of the transaction



By analyzing the transaction flow, it is not difficult to find that the attacker made two calls to the supply() function on lendf.me, but these two calls were independent and did not call the supply() function again in the previous supply() function.

Then, during the second call to the supply() function, the attacker invokes the withdraw() function of lendf.me in his own contract and finally withdraws



Here, it is not difficult to work out that the withdraw() call of the attacker occurs in the transferFrom function, that is, when lendf.me calls the tokensToSend() hook function of the user via transferFrom. Clearly, the attacker reentered the lendf.me contract via the supply() function, causing a reentry attack, so what are the details of the attack? We will follow up the contract code of lendf.me.

The code analysis


After a series of processing, the supply() function of lendf.me calls a doTransferIn function that stores the user-supplied currency into the contract, and then assigns some information about the market variable. To review the attack process just mentioned, the attacker called the withdraw() function in the second supply() function by overloading, that is to say, in the second supply() function, the operation after 1590 lines will not be executed before withdraw(), and the code after 1590 lines will continue to execute after withdraw() execution. This operation caused the attacker to withdraw more money.


Let's dive into the supply() function



According to the above, you can see, in the end () function, to update the balance of the market and users, before this, the user's balance will be good at the beginning of a function to obtain in advance and stored in localResults. UserSupplyCurrent, as follows:



By assigning the value to the localResults variable, the user's transition information is temporarily saved in this variable, and then the attacker executes the withdraw() function. Let's look at the withdraw() function's code:




Here are two key points:

1. At the beginning of the function, the contract first obtains the market and supplyBalance variables of storage.

2. At the end of the withdraw() function, the same logic exists to update the market user's balance information (supplyBalance), and the updated value is the balance after deducting the withdrawal amount of the user.

According to the normal withdraw logic, when withdraw() is executed separately, the user's balance will be deducted and updated normally. However, since the attacker embedded withdraw() in supply(), after the withdraw() function updates the user's balance (supplyBalance), the user's balance will be updated again after the supply() function executes the code, i.e. 1590 lines. The value used for the update would be the original deposit of the user saved in localResults at the beginning of the previous supply() function plus the deposit of the attacker's first call to the supply() function.

In such an operation, although the balance of the user has been deducted after the withdrawal, the logic of the subsequent supply() function will overwrite the value of the user's undeducted withdrawal amount again, causing the attacker to carry out the withdrawal operation, but the balance not only does not deduct, but causes the balance to increase. In this way, attackers can withdraw money at an exponential rate until they empty lendf.me.

Defense advice


For this attack event, the slow fog security team suggests:


1. Add a locking mechanism to key business action methods, such as OpenZeppelin's ReentrancyGuard


2. When developing the contract, the writing style of first changing the variables of this contract and then making external calls is adopted


3. Before launching the project, please invite an excellent third-party security team to conduct a comprehensive security audit and find potential security problems as much as possible

When docking multiple contracts, it is also necessary to check the code security and business security of multi-party contracts, and comprehensively consider the security issues under the combination of various business scenarios


4. The contract as far as possible to set a stop switch, in the event of "black swan" can be timely detection and stop loss


5. Security is dynamic, and each project party also needs to timely capture threat intelligence that may be related to its own project and timely investigate potential security risks


The attached:
OpenZeppelin ReentrancyGuard: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/ReentrancyGuard.sol

Source link:weixin.qq.com



Welcome to join the official BlockBeats community:

Telegram Subscription Group: https://t.me/theblockbeats

Telegram Discussion Group: https://t.me/BlockBeats_App

Official Twitter Account: https://twitter.com/BlockBeatsAsia

举报 Correction/Report
Choose Library
Add Library
Cancel
Finish
Add Library
Visible to myself only
Public
Save
Correction/Report
Submit