
This morning Beijing time, the BNB Chian cross-chain bridge BSC Token Hub was attacked. Hackers used the cross-chain bridge vulnerability to obtain a total of 2 million BNB in two parts, worth about 566 million U.S. dollars.(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 US dollars. The current price is 284 US dollars, a 24-hour drop of 4.24%.
According to BNB Chain, preliminary estimates of the funds withdrawn from the BSC range from $100 million to $110 million. Moreover, Tether also blacklisted the hacker address for the first time. "Thanks to the community and our internal and external security partners, an estimated $7 million has been frozen."
CZ, the founder of Binance, posted on social media that Binance has asked all validators to suspend the BSC network. The user's funds are safe. He apologizes for the inconvenience caused to users and will provide further updates accordingly.
secondary title
The samczsun analysis article is as follows:
(1) Five hours ago, attackers stole 2 million BNB (approximately $566 million) from Binance Bridge. I have since been working closely with various parties to uncover how this all happened.

(2) The cause of the incident was 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 runaway project rug, or there was a massive hack going on.

(3) At first, I thought @VenusProtocol was hacked again. However, it didn't take long for me to determine that the attackers "really" deposited over $200 million into Venus. That's when I needed to figure out where those funds came from.

(4) The answer is that the attacker somehow convinced the Binance cross-chain bridge to send them (the hacker) 1,000,000 BNB directly, twice.

(5) Either Binance launched the largest "gift package" in the history of Web3, or the attacker discovered a serious vulnerability. I start by comparing the attacker's transactions to legitimate withdrawals. The first thing I noticed was that the attacker always used the same height - 110217401, while the legitimate withdrawals used a much higher height like 270822321.


(6) I also noticed that the attacker's proof is significantly shorter than the proof of a legitimate withdrawal. These two facts convince me that the attacker has found a way to forge the proof for this particular block (110217401). Now, I have to figure out how these proofs work.

(7) On Binance, there is a special precompiled contract for verifying the IAVL tree. Don't worry if you don't know anything about IAVL trees, because 95% of them I don't. Fortunately, all you and I need are the remaining 5%.

(8) Basically, when you validate an IAVL tree, you specify a list of "operations". Binance cross-chain bridges usually require two operations: the "iavl:v" operation and the "multistore" operation. Here is their implementation: https://github.com/bnb-chain/bsc/blob/46d185b4cfed54436f526b24c47b15ed58a5e1bb/core/vm/lightclient/multistoreproof.go#L106-L125
(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 (the hash of the specified block: 110217401).
(10) By looking at the implementation, we can see that manipulating the root hash is impossible, or at least very difficult. This means we need our input value to be 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 root hash? It happens in a function called COMPUTEHASH. At a very high level, it recursively walks each path and leaf node and does a lot of hashing.
https://github.com/cosmos/iavl/blob/de0740903a67b624d887f9055d4c60175dcfa758/proof_range.go#L237-L290
(13) The implementation details are actually not important, what matters is that due to the way hash functions work, we can basically say with certainty that any (path, nleaf) pair will result in a unique hash. These have to remain the same if we want to falsify evidence.
(14) Looking at how the proof is laid out in the legitimate transaction, we see that it has a very long path, no internal nodes, only one leaf node, and this leaf node 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 one last hurdle. How do we actually get COMPUTEHASH to return the root hash we want? Well, note that eventually we will need a path that contains a non-zero right hash. When we find a match, we assert that it matches the intermediate root hash.

(17) Let's instrument the code a bit so we can figure out what hash we need, then all that's left is to put it together, we'll take the legal proof 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 tune our leaf nodes to exit early with the correct root hash
https://gist.github.com/samczsun/8635f49fac0ec66a5a61080835cae3db…

(18) It is worth noting that this is not the exact method used by the attackers. Their proof paths are much shorter, and I'm not sure how exactly they were generated. However, the rest of the exploit is the same and I believe it is valuable to show how to build it from scratch.
(19) In summary, there is a bug in the way the Binance cross-chain bridge verifies proofs that could allow an attacker to forge arbitrary messages. Fortunately, the attackers here only forged two messages, but the damage could have been far worse.


