Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Binance Smart Chain Token Bridge Hack- 1104

Andrey Bachurin - PT Swarm SecurityPosted 2 Years Ago
  • The Binance has a token hub bridge that allows interoperability between two chains. These two chains are the EVM compatible Binance Smart Chain (BSC) and the Binance Beacon Chain used for management purposes. The currency of these chains is BNB.
  • Bridges do not work as you'd expect; it's more of a lockbox than anything else. Chain A has ownership of some tokens on Chain B. So, we look the Chain A tokens then unlock them for the specific user on Chain B. In the case of Binance, the logic for going to Chain B was busted.
  • When Chain B does the verification from the Chain A blockchain in Solidity, it uses a type of binary tree that can be used for verification called a Merkle Tree. This tree allows for the verification of the existence of a transaction on the other chain. Any discrepancy will indicate that the data in the node has been tampered with.
  • The BSC bridge uses a balanced binary tree called an AVL tree. The function handlePackage is made in order to add this information to chain B. It should be noted that this function is only callable by a relayer.
  • In the land of Cosmos, the relayer is how IBC communicates that a transaction on Chain A has occurred that Chain B cares about. A relayer doesn't need to be 100% trusted. Because, at the end of the day, the merkle proof speaks for itself. The relayer for BNB will parse the events at the very end of a block and send this to chain B.
  • To send it to chain B, there are 4 parameters: a source chain ID, destination chain ID, a channel ID and a sequence number. After this initial handshake, the relayer calls Chain B with the transaction data, the proof and the block height. This is how the data goes from a Chain A request to a Chain B request.
  • The Merkle proof library in Solidity was a precompiled IAVL library written in Go that directly interacts with Cosmos via a special EVM hook specific to Binance. Within Go, the function computes the root hash and verifies that it matches the hash against the new data being provided. If this is true, then the transaction must be legitimate.
  • The tree verification algorithm assumes that only one leaf node will exist. If there's a left node (if statement), then it allows verifies that. If there's a right (else statement) node, then it only verifies that. This becomes a problem when there are two leafs, which is 100% possible. With the logic of the program, we can provide a right node that will never be verified!
  • To exploit this, the attacker took a legitimate transaction and modified the payload to add the right node. The node said that a transaction of 2 million BNB with each BNB worth $293 at the time, was sent to them. Once they had done this, they took the money out of the bridge and laundered it to some other places. This resulted in a $586 million dollar hack.
  • In the aftermath of this, Binance forked the BSC blockchain to remove this. Additionally, USDT blocked the attackers address, preventing them from accessing a percentage of their stolen funds. To fix this, the proof errors out if there is more than one child. Overall, an interesting dive into the Cosmos and Binance eco-system.