The biggest DeFi hack of the year! Beosin on the Poly Network Attack Full Explanation

BEOSIN
5 min readAug 11, 2021

--

On the evening of August 10, the public opinion monitoring of ChainBuilder — Blockchain Security Situational Awareness Platform (Beosin-Eagle Eye) showed that the cross-chain protocol Poly Network was attacked and nearly US$600 million in funds were stolen from three chains, Ethereum, BinanceChain and Polygon.

Poly Network was once considered to be the “best” cross-chain interoperability protocol on the market today for true “heterogeneous cross-chain”.

The attack first occurred on August 10 at 17:55, with hackers transferring 96.38 million USDC, 1032 WBTC and other assets from Poly Network smart contracts one after another at Ether, with a total value of over $260 million; from 18:04, with hackers transferring 85.08 million USDC from the project’s smart contracts at Polygon; and from 18:08, with hackers transferring 87.6 million USDC, 26,629 ETH and other assets from the project’s smart contracts at BSC transferred 87.6 million USDC, 26,629 ETH and other assets from from the project’s smart contracts.

This is the largest hack in the entire history of crypto, surpassing the infamous Mt.Gox incident (744,408 BTC, worth about $400 million at the time) and the 2018 Coincheck case (523 million XEM, worth about $534 million at the time). Regarding the exact cause of this incident, the Beosin technical team has been conducting real-time monitoring to track the principle and technical details of the vulnerability.

After analysis, the Beosin technical team found that the attacker took advantage of a logic flaw in the EthCrossChainManager contract to call the putCurEpochConPubKeyBytes function in the EthCrossChainData contract to change the Keeper to its own address, and then used that address to sign the transactions to extract the tokens, thus siphoning off a large amount of tokens from the LockProxy contract.

Attacker’s address

BSC:0x0D6e286A7cfD25E0c01fEe9756765D8033B32C71

ETH:0xC8a65Fadf0e0dDAf421F28FEAb69Bf6E2E589963

Polygon:0x5dc3603C9D42Ff184153a8a9094a73d461663214

Contracts under attack.

BSC:

A:0x7ceA671DABFBa880aF6723bDdd6B9f4caA15C87B(EthCrossChainManager)

B:0x2f7ac9436ba4B548f9582af91CA1Ef02cd2F1f03(LockProxy)

ETH:

C:0x838bf9E95CB12Dd76a54C9f9D2E3082EAF928270(EthCrossChainManager)

D:0x250e76987d838a75310c34bf422ea9f1AC4Cc906(LockProxy)

Polygon:

E:0xABD7f7B89c5fD5D0AEf06165f8173b1b83d7D5c9(EthCrossChainManager)

F:0x28FF66a1B95d7CAcf8eDED2e658f768F44841212(LockProxy)

Attack on trade.

BSC:

0x3eba3f1fb50c4cbe76e7cc4dcc14ac7544762a0e785cf22034f175f67c8d3be9

0x4e57f59395aca4847c4d001db4a980b92aab7676bc0e2d57ee39e83502527d6c

0x50105b6d07b4d738cd11b4b8ae16943bed09c7ce724dc8b171c74155dd496c25

0xd65025a2dd953f529815bd3c669ada635c6001b3cc50e042f9477c7db077b4c9

0xea37b320843f75a8a849fdf13cd357cb64761a848d48a516c3cac5bbd6caaad5

ETH:

0xb1f70464bd95b774c6ce60fc706eb5f9e35cb5f06e6cfe7c17dcda46ffd59581

0xad7a2c70c958fcd3effbf374d0acf3774a9257577625ae4c838e24b0de17602a

Polygon:

0x8c8b43012773b8948cfb0c66f69bfa7513817e35052ace91e2ed7eb9e8cacb95

0x1d260d040f67eb2f3e474418bf85cc50b70101ca2473109fa1bf1e54525a3e01

0xfbe66beaadf82cc51a8739f387415da1f638d0654a28a1532c6333feb2857790

On the BSC, the attacker first calls the verifyHeaderAndExecuteTx (0xd450e04c) function in the EthCrossChainManager contract by passing carefully constructed data. Since the verifyHeaderAndExecuteTx function calls the internal function _executeCrossChainTx and uses a call in that internal function, the attacker controls the call’s parameter _ method, successfully calling the putCurEpochConPubKeyBytes function in the EthCrossChainData contract as the EthCrossChainManager contract to change the Keeper to its own address ( 0xa87fb85a93ca072cd4e5f0d4f178bc831df8a00b). This step of the operation is to subsequently be able to obtain a transaction with a valid Keeper signature and then extract the tokens from the contract.

The above call to the attacker-constructed _method is not actually putCurEpochConPubKeyBytes, because only the function name in the call is user-controllable and the parameters are of a fixed number and type. The attacker implements the call to the putCurEpochConPubKeyBytes function in the EthCrossChainData contract by constructing the f1121318093 function with the same function signature as putCurEpochConPubKeyBytes.

After completing the modification of the Keeper, the attacker can then sign any transaction. The attacker removes all ETH, BTCB, BUSD and USDC tokens from the B contract with multiple transactions signed by a valid Keeper (after the signature has been modified by the attacker to his own address).

Since ETH and Polygon have the same code and Keeper as on BSC, the attacker, after completing the attack on BSC, replayed the previously constructed data on ETH and Polygon, modifying the Keeper on ETH and Polygon to its own address as well (0xa87fb85a93ca072cd4e5f0d4f178bc831df8a00b).

Then using the same attack technique, all of the ETH, USDC, WBTC, UNI, DAI, SHIB, WETH, FEI, USDT and renBTC in the D contract and all of the USDC in the F contract were taken out.

Attackers return USD 1.01 million at Polygon.

The main reason for this attack is that there is a problem with the contract permission management logic. Any user can call the verifyHeaderAndExecuteTx function to execute a transaction, and when making a call inside it, the function name can be controlled by the user, and a malicious user can call part of the function through an elaborate data exception. Also the EthCrossChainManager contract has permission to modify the Keeper, normally through the changeBookKeeper function, but in this attack the attacker is successfully modifying the Keeper through the call call in the verifyHeaderAndExecuteTx function via the carefully constructed data The Keeper address, which in turn could sign the transaction, resulted in the most damaging attack since Defi’s inception.

Possibly due to pressure from multiple parties, the hackers who attacked Poly Network began to return assets, having returned 10,100USDC on Polygon in block 17862254 and 1 million USDC on Polygon in block 17862497.

Beosin would like to remind developers that when using call calls, they need to pay particular attention to cases where the parameters are user controllable, and some special contracts and functions need to be strictly controlled for permissions to avoid irreparable damage caused by abnormal calls.

--

--

BEOSIN
BEOSIN

Written by BEOSIN

Blockchian Security · IDE · Beosin-VaaS · Formal Verification · SAS | China leading enterprise in blockchain security field

No responses yet