212 total views
SlowMist believes that the attack is mainly caused by the modification of the keeper of the EthCrossChainData contract, rather than the leakage of the private key. At present, hackers have begun to return funds one after another.
Written by: SlowMist Security Team
On August 10, 2021, according to the news from the SlowMist Zone, the cross-chain interoperability protocol Poly Network was attacked by hackers. The SlowMist security team immediately intervened in the analysis and shared the analysis results as follows.
Poly Network is a cross-chain organization co-sponsored by Neo, Ontology, and Switcheo Foundation as founding members, and distributed technology as the technology provider.
As shown in the figure below, we can clearly see the architecture design of Poly Network through the official introduction: users can initiate cross-chain transactions on the source chain. After the transaction is confirmed, the source chain Relayer synchronizes the block header information to the Poly Chain, and then the Poly Chain The block header information is synchronized to the target chain Relayer, and the target chain Relayer transfers the verification information to the target chain, and then performs block header verification on the target chain and executes the user’s expected transaction.
The following are the specific addresses involved in this attack:
Attack the core
- The source chain did not check the data of the initiated cross-chain operation.
- The target chain did not check the parsed target call contract and call parameters.
- The owner of the EthCrossChainData contract is EthCrossChainManager.
- bytes4(keccak256(abi.encodePacked(_method, “(bytes,bytes,uint64)”))) can be collided by hash.
Poly Network will deploy smart contracts on each chain for cross-chain interoperability (analysis will take the smart contract deployed on Ethereum as an example), where the EthCrossChainManager contract is used to verify the block header synchronized by the Poly Chain to confirm the cross-chain information real. The EthCrossChainData contract is used to store cross-chain data, and the public key of the relay chain validator (ie Keeper) is also stored in this contract. LockProxy is used for asset management.
In this attack, the attacker completed this attack in two steps. Let’s analyze it in detail next:
First, the attacker initiates a cross-chain transaction by calling the crossChain function on other chains to construct data.
We cut into this function for analysis:
From the above figure, we can clearly see that this function is only used to help the user construct makeTxParam and store the constructed hash for subsequent verification. It does not impose any restrictions on the cross-chain operation parameters passed in by the user, so the attacker It is completely possible to make the Relayer synchronize it to the Poly Chain unsuspectingly by constructing any data you want, and synchronize it to the Ethereum Relayer through the Poly Chain.
Then the Relayer on Ethereum calls the EthCrossChainManager contract
The verifyHeaderAndExecuteTx function submits the block header information to verify the authenticity of this cross-chain information.
We cut into this function for analysis:
From the above code, we can see that it first deserializes the block header to solve the specific information that needs to be verified. Then call the getCurEpochConPubKeyBytes function to get the Keeper public key from the EthCrossChainData contract, and get the Keeper address through the deserializeKeepers function.
Next, ECCUtils.verifySig will be used to verify whether the signature is a Keeper. From the following code, we can find that the signer’s vrs will be cut out in the verifySig function, and the signer’s address will be obtained through the ecrecover interface, and then the containMAddresses function will be called to compare whether the signer is Keeper, as long as the number of Keeper signatures meets the requirements, it can pass the inspection. The number requirement is n-(n-1) / 3) passed in by the EthCrossChainManager contract.
After signature verification, Merkle root verification will be carried out through ECCUtils.merkleProve. As long as it is a normal cross-chain operation, it can pass this check. It will then check whether the transaction is sent repeatedly and store the verified data. You only need to ensure that there is no duplicate submission here.
Finally, and the most critical step, it will execute the constructed data by internally calling the _executeCrossChainTx function.
From the above figure, we can see that the _executeCrossChainTx function directly executes the transaction in the way of _toContract.call without checking the passed parameters such as _toContract and _method.
Among them, from the data on the chain, we can see that the owner of the EthCrossChainData contract is the EthCrossChainManager contract. Previously, we knew that the public key of the relay chain verifier (i.e. Keeper) was stored in the EthCrossChainData contract, and the putCurEpochConPubKeyBytes function in this contract could directly modify the Keeper public key. key.
After the above analysis, the result is very clear. The attacker only needs to normally initiate a cross-chain operation transaction on other chains through crossChain. The purpose of this transaction is to call the putCurEpochConPubKeyBytes function of the EthCrossChainData contract to modify the Keeper role. Then through the normal cross-chain process, Keeper will parse the target contract and call parameters requested by the user, construct a new transaction and submit it to Ethereum. This is essentially just a normal cross-chain operation, so you can directly pass the Keeper check and Merkel root check. Finally, the operation to modify the Keeper is successfully executed.
But we noticed that the putCurEpochStartHeight function is defined as
function putCurEpochConPubKeyBytes(bytes calldata curEpochPkBytes) external returns (bool);
And the execution of the _executeCrossChainTx function is defined as
We can know that the function signatures of these two functions are definitely completely different when the _method passed in under normal circumstances is putCurEpochStartHeight, so the putCurEpochStartHeight function cannot be called theoretically through _toContract.call. But _method is controllable by an attacker. It can obtain the same function signature as calling the putCurEpochConPubKeyBytes function by enumerating each character combination, which requires only the first 4 bytes to be enumerated. We can also try enumeration verification ourselves, as shown below:
It can be seen that the first four bytes are consistent with the putCurEpochConPubKeyBytes function
So far we have recovered the details of the attacker’s attack.
By analyzing the data on the chain, we can find that the attacker replaced Keeper with
In the end, the attacker only needs to sign with the replaced Keeper address to transfer the assets under management by calling the LockProxy contract through all checks and executions.
The attacker carefully constructs an operation on the source chain to modify the Keeper of the target chain.
Use the official Relayer to normally submit data on the target chain and perform the replacement Keeper operation.
The attacker uses the replaced Keeper address to sign and submit the asset transfer operation to EthCrossChainManager for verification.
Verify that the Keeper is the address that the attacker has replaced and pass the check, and the asset is transferred to the address specified by the attacker.
Make a profit and leave.
MistTrack analysis process
According to the analysis and statistics of the SlowMist AML team, the total loss of this attack exceeded 610 million U.S. dollars !
details as follows:
Capital flow analysis
Slow fog AML AML’s MistTrack tracking system analysis found that the attacker is the initial source of funds Monroe currency (XMR).
Then it changed to BNB/ETH/MATIC and other currencies in the exchange and withdrew the coins to 3 addresses respectively, and soon launched an attack on 3 chains.
Funding situation (as of 13:00 on August 11, Beijing time)
On BSC :
Hacker address 1. The hacker added nearly 120 million U.S. dollars (including about 32.1 million BUSD and about 87.6 million USDC) of liquidity to the Curve fork project Ellipsis Finance, and the market is still making no changes.
There is no change in funds.
On Ethereum :
1) Hacking address 3, only a sum of 13.37 ETH was transferred to the address
2) Hackers added more than 97.06 million U.S. dollars (including 670,000 DAI and 96.38 million USDC) of liquidity on Curve. Later, the liquidity was withdrawn and 96.38 million USDC and 670,000 DAI were exchanged for 96.94 million DAI. The funds remained at address 3. Currently, 33.43 million USDT has been frozen by Tether.
Questions and answers
Note: eccm is the abbreviation of the EthCrossChainManager contract, and eccd is the abbreviation of the EthCrossChainData contract.
Question : Why can the keeper be replaced successfully, and the contract code is not authenticated?
Answer : The eccd contract is authenticated. Only the owner is allowed to call putCurEpochConPubKeyBytes to change the keeper. Because the owner of the eccd contract is eccm, the value of the keeper can be changed through eccm.
Q : Why can I sign a transaction to replace the keeper?
Answer : Because the data to be executed across the chain has not been properly judged toContract, the original keeper may have signed a normal cross-chain transaction, but it is a transaction to replace the keeper.
Question : Why can I bypass the limitation of code bytes4(keccak256(abi.encodePacked(_method, “(bytes,bytes,uint64)”))) and then execute the putCurEpochConPubKeyBytes(bytes) function?
Answer : The function signature uses keccak-256 for hashing, and then takes the previous 4bytes. In this case, it is easier to be collided by the hash.
Question : How can the hacker’s transaction of changing the keeper be signed by the old keeper?
Answer : Keepers is a chain repeater (Replayer), which will sign all cross-chain requests of normal users. When a user initiates a cross-chain transaction on BSC, keepers will parse the target contract and call parameters requested by the user, construct a new transaction and submit it to Ethereum, and use the eccm contract to call the target contained in the user transaction on Ethereum contract. The hacker’s transaction to replace the keeper is essentially a normal cross-chain transaction, except that the target contract called is the eccd contract, and the parameter of the call is to replace the keeper, so it can be signed normally.
This attack is mainly because the keeper of the EthCrossChainData contract can be modified by the EthCrossChainManager contract, and the verifyHeaderAndExecuteTx function of the EthCrossChainManager contract can execute the data passed in by the user through the _executeCrossChainTx function. Therefore, the attacker uses this function to pass in carefully constructed data to modify the address specified by the attacker by the keeper of the EthCrossChainData contract. It is not the case that this event occurred due to the leakage of the keeper’s private key.
SlowMist AML’s MistTrack anti-money laundering tracking system will continue to monitor the transfer of stolen funds, block all wallet addresses controlled by the attacker, and remind exchanges and wallets to strengthen address monitoring to prevent related malicious funds from flowing into the platform. In addition, special thanks to the teams such as Hoo, Poly Network, Huobi Zlabs, Chain Wen, WePiggy, TokenPocket Wallet, Bibox, Ouke Cloud Chain, and many individual partners, and many individual partners for synchronizing with the SlowMist security team in a timely manner under the premise of compliance. Information, bought valuable time for tracking the attacker.
At present, with the efforts of many parties, hackers have begun to return funds one after another.
Blockcast.cc does not endorse any content or product on this page. While we aim at providing you all important information that we could obtain, readers should do their own research before taking any actions related to the company and carry full responsibility for their decisions, nor can this article be considered as investment advice or recommendations. Every investment and trading move involves risk, you should conduct your own research when making a decision.