On the morning of October 7th,BNB Chain Cross-chainThe bridge BSC Token Hub was attacked. Hackers took advantage of the cross-chain bridge vulnerability to obtain a total of 2 million BNB, worth about $566 million. (Note: BSC Token Hub is a cross-chain bridge between BNB Beacon Chain (BEP2) and BNB Chain (BEP20 or BSC).)
As soon as the news came out, the price of BNB fell by nearly 5% within 2 hours, falling to a low of $278.7, which was $285.34 at the time of writing, a 3.2% drop in 24 hours.
According to BNB Chain, funds withdrawn from BSC are initially estimated to be between $100 million and $110 million. In addition, Tether also blacklisted the hacker address for the first time. BNB Chain officially stated, “Thanks to the community and our internal and external security partners, an estimated $7 million has been frozen.”
Binance founder CZ tweeted,BinanceAll validators have been asked to suspend the BSC network, user funds are safe, we apologize for the inconvenience and will provide further updates accordingly.
For specific attack methods,Paradigm Researcher Samczsun wrote that the data on the chain and related codes show that there is a bug in the verification method of the BSC cross-chain bridge, which may allow the attacker to forge any message; in this attack, the attacker’s forged message passed the verification of the BSC cross-chain bridge. , causing the cross-chain bridge to send 2 million BNB to the attacker’s address.
Samczsun analyzed the article as follows:
(1) Five hours ago, attackers stole 2 million BNB (~$566 million) from Binance Bridge. I’ve been working closely with multiple parties since then to uncover how this all happened.
(2) The reason for this is that @zachxbt suddenly sent me the attacker’s address. When I clicked in, I saw an account worth hundreds of millions of dollars; either there was a project Rug Pull running away, or there was a massive hack in progress.
(3) At first, I thought @VenusProtocol was hacked again. However, it soon became clear that the attackers “really” deposited over $200 million into Venus. At this point, I need to figure out the source of these funds.
(4) The answer is that the attackers somehow persuaded Binance to cross the bridge and send them (the hackers) 1,000,000 BNB directly, twice.
(5) Either Binance launched the biggest “gift package” ever for Web3, or the attackers discovered a serious vulnerability. I start by comparing the attacker’s transaction with a legitimate withdrawal. The first thing I noticed is that the height used by the attacker is always the same – 110217401, while the height used by legitimate withdrawals is much larger, such as 270822321.
(6) I also noticed that the attacker’s proof is significantly shorter than the proof of legitimate withdrawal. These two facts convince me that the attacker has found a way to forge the proof of this particular block (110217401). Now, I have to figure out how these proofs work.
(7) On Binance, there is a special precompiled contract for validating IAVL trees. Don’t worry if you don’t know anything about IAVL trees, because I don’t know 95% of them either. Fortunately, all you and I need is to know the remaining 5%.
(8) Basically, when you validate an IAVL tree, you specify a list of “actions”. Binance cross-chain bridge usually requires two operations: “iavl:v” operation and “multistore” operation. Please refer to their implementation.
(9) In order to forge the proof, we need both operations to succeed, and we need the last operation (multistore) to return a fixed value (hash of the specified block: 110217401).
(10) By looking at the implementation, we can see that it is impossible, or very difficult, to manipulate the root hash. This means, we need the input value equal to one of the commit IDs.
(11) The input value of the “multistore” operation is the output value of the “iavl:v” operation. This means, we want to somehow control the root variable here, while still passing value validation.
(12) So how to calculate the root hash? It happens in a function called COMPUTEHASH. At a very high level, it recursively traverses every path and leaf node and does a lot of hashing.
(13) Actually, the implementation details don’t matter, what matters is that because of the way hash functions work, we can basically say with certainty that any (path, nleaf) pair will yield a unique hash. If we want to falsify evidence, these have to stay the same.
(14) Looking at how the proof is laid out in a legitimate transaction, we see that it has a long path with no internal nodes, just a leaf node that contains the hash of our malicious payload! If we cannot modify this leaf node, then we need to add a new leaf node.
(15) Of course, if we add a new leaf node, we also need to add a new internal node to match.
(16) Now we just have to face the last hurdle. How do we actually get COMPUTEHASH to return the root hash we want? Well, note that eventually we will need a path containing a non-zero right hash. When we find a match, we assert that it matches the intermediate root hash.
(17) Let’s test the code a little bit so we can figure out what hashes we need, then all that’s left is to put them together, we’ll take the proof of legitimacy and modify it so that:
1) We add a new leaf node for the fake payload;
2) We add a blank internal node to satisfy the prover;
3) We adjust our leaf nodes to exit early with the correct root hash.
(18) It is worth noting that this is not the exact method used by attackers. Their proof path is much shorter and I’m not sure how exactly they were generated. However, the rest of the exploit is the same and I believe there is value in showing how to build it from scratch.
(19) In conclusion, there is a bug in the way Binance cross-chain bridge verifies proofs that could allow an attacker to forge arbitrary messages. Fortunately, the attacker here only forged two messages, but the damage could have been much more severe.