In this blog, we want to review the whole process of the Poly Network Hack and discuss the lessons learnt.
We knew that the poly Network was being hacked on Aug 10, 2021 (we use +8 time zone in this blog). However, there is no clue of how the hack was happening, and what is the root cause of the hack. As a security research team, we started our investigation.
Step 1: Find the attack transaction
We replayed the attack transaction 0xd8c1f7424593ddba11a0e072b61082bf3d931583cb75f7843fc2a8685d20033a in our transaction virtualization system (https://tx.blocksecteam.com).
The trace is quite simple, which is different from other attacks that manipulate the price. They usually have very complicated function invocations (See the Popsicle hack.)
Step 2: Analyze the contract code
After getting the attack trace, we need to review the source code of the contract. Surprisingly, the poly network does NOT have verified source code on Etherscan. However, we managed to find the released source code on github.
After reviewing the source code, we did not find any obvious code vulnerability. We also compared the attack trace with a legitimate transaction trace and found that they are similar.
Step 3: Recover the critical states
Then we recovered the critical states during the attack. Since the attack is launched from the invocation of VerifyHeaderAndExecuteTxEvent, we recovered several critical variable values, which we have shared in our first analysis [1].
During this process, we found that there is only one keeper (see the above figure). Since the value is obtained from the attack trace and the attack transaction has passed all the signature verification, we thought the potential reason could be the leakage of the private key or a bug in the signing process of the server [1].
However, we made a mistake here. Analyzing an attack is like peeling an onion. You peel it one layer at a time, until you locate the real “root root root” cause. At that time, we did not peel the onion further to see whether the keeper had been changed!
Step 4: New clue
A couple of hours later, Kelvin and slow mist gave new clues on Twitter, showing the keep has been changed. The change process abuses the hash collision to invoke a powerful function — a “smart” hack.
Now we realized that our first analysis is not complete. Based on the latest information, we replayed the transaction that changed the keeper. Still the trace is a very simple.
But remember that, during this transaction, there are four keepers (instead of one). All these keys are the same with other legitimate transactions — which means the keys are legitimate. Here comes the question: why the transaction that changes the keeper can be put on the chain and get executed in the first place?
Step 5: Locate the source transaction
We then try to locate the source transaction since the Poly network is a cross-chain bridge. There should exist a source transaction somewhere. We did this by decoding the critical variable (as shown in the following picture). It shows the transaction hash of the source chain and the poly chain.
There is a trick that has not been mentioned elsewhere. The tx hash value in the variable has a different representation with the official value in the poly chain. For instance, the tx hash of the poly chain in the figure is 0x80cc978479eb082e1e656993c63dee7a5d08a00dc2b2aab88bc0e465cfa0721a。But in the poly chain brower, the hash value is 1a72a0cf65e4c08bb8aab2c20da0085d7aee3dc69369651e2e08eb798497cc80(do you see the difference?). We shared our findings in the EthereumSecurity tg group on Aug 11 16:55.
Step 6: Locate the root cause
But still, we cannot answer the question “why the transaction to change the keeper” can be packed on the chain? To answer this question, we started from the Ontology chain and found the transaction flow:
Ontology transaction -> Ontology relayer -> Poly chain -> Ethereum relayer -> Ethereum
We then read the source code of the Ontology chain and the relayers. After a couple of hours, we found that the Ontology relayer does not have enough validation for the cross-chain transaction. This can let the malicious transaction pack on the poly chain. After that the system is pwned.
After internal discussion and challenging, we released our findings on Aug 12 02:41 on Twitter and medium[3].
Lessons
-
Security by design. Security should be in the whole process of the DeFi project. Users entrust their money to the project. In turn the project should deserve the trust. Unfortunately, we saw the ignorance of the security by the Poly network. For instance, the lack of validation is an old school security vulnerability, which I taught on the undergraduate class.
-
There is no verified source code for such as DeFi project with more than 600M TVL. The basis of the decentralized infrastructure is trust and the foundation of the trust is transparency. Unfortunately, users are willing to put their money into a blackbox project, which surprises and worries me. How to improve the security sense of user probably needs a new solution.
Reference
[1]https://blocksecteam.medium.com/the-initial-analysis-of-the-polynetwork-hack-270ac6072e2a
[2]https://twitter.com/kelvinfichter/status/1425290462076747777
[3]https://blocksecteam.medium.com/the-further-analysis-of-the-poly-network-attack-6c459199c057
Credits: Yufeng Hu, Siwei Wu, Lei Wu, Yajin Zhou @ BlockSecTeam