The initial analysis of the PolyNetwork Hack

By BlockSec

The PolyNetwork has been hacked and more than 300 million USDs have been stolen. The attacker performed the attack on multiple chains. In this blog, we use the attack transaction on Ethereum (0xd8c1f7424593ddba11a0e072b61082bf3d931583cb75f7843fc2a8685d20033a ) to analyze the possible reason of the hack. Our initial analysis shows that one possible reason could be either the leakage of the private key that is used to sign the cross-chain message, or there is a bug in the signing process of the PolyNetwork that has been abused to sign a crafted message.

Disclaimer: This blog only contains the result of our initial analysis based on the onchain data on Ethereum. We cannot verify our findings without further information from Poly Network.

Update 2021/08/12: The further information shows that the cause of the attack is because the keeper has been modified by the attacker (not because of the leakage of the private key). We have a further analysis to answer the question why the transaction to change the keeper can be executed in the first place.

Transaction and call trace

We use our transaction analysis system(https://tx.blocksecteam.com) to recover the trace.

Attacker -> EthCrossChainManager -> EthCrossChainData -> LockProxy -> managerProxyContractforLockProxy

  • 0xc8a65fadf0e0ddaf421f28feab69bf6e2e589963: Attacker
  • 0x838bf9e95cb12dd76a54c9f9d2e3082eaf928270: EthCrossChainManager
  • 0xcf2afe102057ba5c16f899271045a0a37fcb10f2: EthCrossChainData
  • 0x250e76987d838a75310c34bf422ea9f1ac4cc906: LockProxy
  • 0x5a51e2ebf8d136926b9ca7b59b60464e7c44d2eb: managerProxyContract for LockProxy

Function Signatures:

  • d450e04c (verifyHeaderAndExecuteTx)
  • 69d48074 (getCurEpochConPubKeyBytes)
  • 5ac40790 (getCurEpochStartHeight)
  • 0586763c (checkIfFromChainTxExist)
  • e90bfdcf (markFromChainTxExist(uint64,bytes32))

The main process of the attack

The main process of the attack is that the attacker passed the signed data to the function verifyHeaderAndExecuteTx(). This function will decode the data and verify the signatures that are used to sign the data. If this process passes, the method (and the contract address) specified in the message will be executed. During this attack, the unlock function of the smart contract 0x250e76987d838a75310c34bf422ea9f1ac4cc906 is invoked to transfer the Fei to the attacker.

In summary, the attack is due to the valid parameters passed to the verifyHeaderAndExecuteTx function. And the parameters can pass the signature verification process. After that, the transaction specified in the message will be executed (like the arbitrary command execution in software security.)

To better understand this process, we recover the critical values of the call trace.

Function: verifyHeaderAndExecuteTx:

verifySig

unlock

The variable of managerProxyContract in the LockProxy. It matches the value of the caller address of the unlock function.

Conclusion

From the recovered values, we find that:

  1. The attacker provides a valid signed message to the function verifyHeaderAndExecuteTx
  2. The onlyManagerContract modifier in the LockProxy smart contract is NOT bypassed.

Based on these two observations, we suspect that

  1. The attacker may have the legitimate keys to sign the messages, which indicate the signing keys may have been leaked.

Or

2. There is a bug in the signing process of the PolyNetwork that has been abused to sign a crafted message.

However, we do not have further offchain data to verify our findings. We hope our analysis can be helpful for further investigation.

Credits: Yufeng Hu, Siwei Wu, Lei Wu, Yajin Zhou @BlockSec

Twitter: https://twitter.com/BlockSecTeam