Binance Chain Bridge Exploitation Writeup - Part 2
This is the second part of our analysis on Binance Chain's bridge hack, focus on hacker transactions and exploitation payloads.
by Verichains Team
This is the second part of our analysis on Binance Chain’s bridge hack, focus on hacker transactions and exploitation payloads. This analysis also answers @samczsun's questions in his early tweets, in which he wondered how the attacker's payload was much shorter than his me.
The hacker transaction is at https://bscscan.com/tx/0xebf83628ba893d35b496121fb8201666b8e09f3cbadf0e269162baa72efe3b8b. Decoding the transaction data, we got the following arguments that will be passed to the function
CrossChain.sol smart contract (link):
0 payload bytes 0x000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f100
2 height uint64 110217401
3 packageSequence uint64 17684572
4 channelId uint8 2
payloadcontains information about the cross-chain transfer (of course it did not actually happen) including BSC recipient address and token amount which the attacker has set to his/her own address and 1 million BNB respectively.
proofis an IAVL/Merkle proof that asserts the integrity of
heightis (at least) the BC (not BSC) block height at which the transfer occurred. The
appHashof BC corresponding to
heightwill be retrieved for verifying
packageSequenceacts like a TCP sequence number to assure that packages relayed to BSC can not be replayed and arrive in order.
channelIdis routing information that is used to select the next appropriate contract to handle the package payload after its verification succeeds. Here,
channelId == 2indicates a cross-transfer (BC to BSC) package which should be handled by the
The way BC to BSC cross-chain communication works is that every-time a package needs to be sent to BSC, a
key will be constructed from
channelId, and its associated
value, which is essentially the package payload, will be stored in the verifiable key-value store of BC and thus, updating BC
appHash. Later on, the package is relayed to BSC together with
proof that proves the correctness of the corresponding
value pair in BC store. This is basically the light-client technique for cross-chain communication.
Next, we will analyze
proof essentially contains 2 parts.
The first part regards to the multistore architecture of BC. Basically, BC
appHash is the hash of all its sub-store root hashes, including the one named
ibc (short for Inter-Blockchain Communication) in which the
value pair mentioned earlier is actually stored.
proof carries all the sub-store hashes so
ibc root hash could be verified against
appHash. Compared with a valid proof, the attacker did not change this part.
The second part is about proving that a leaf containing
value does actually exist in
ibc IAVL tree given its root hash. The technique used to forge this part has been described earlier. Please notice that both
Right fields of
Proof.LeftPath are filled:
LeftPath, we deduce that the
ibc tree snapshot at BC block height 110217401 looks like this:
And the malicious second part is as follows:
So, the BC block height 110217401 chosen by the attacker is likely for minimizing the proof size as the
ibc tree at that time had only a few nodes. Maybe it helped reduce some gas cost when submitting the malicious transaction, or the attacker just prefers a concise proof over longer ones.
This analysis also answers @samczsun's questions in his early tweets, in which he wondered how the attacker's payload was much shorter. As long as the IAVL tree contains at least 2 leafs, the attack is already feasible. Therefore, the proof could be made short, and the attacker chose to do so.
Thanks for reading Verichains Lab! Subscribe for free to receive new posts and support my work.