Breakdown: How the hacker stole 80k ETH from the Solana Wormhole bridge
On Wednesday, a hacker managed to steal 80,000 ether (ETH) out of Solana through the Solana-Ethereum bridge Wormhole. Here’s how the hacker pulled it off.
One of the worst hacks against the Solana blockchain happened on Wednesday when a hacker managed to transfer 80,000 ether (ETH), over $214 million at the moment of writing, out of the Solana system and into the Ethereum blockchain through the Wormhole bridge – a service providing the ability to transfer funds between the different blockchains.
Explained in a tweet thread by the pseudonymous Twitter profile smartcontracts, the hacker finalized the exploit by transferring the 80,000 ETH out of the Wormhole smart contract on Ethereum in a single transaction. As it turned out, this was just the final move in a series of hacks that enabled the hacker to steal the funds.
“Although it’s dramatic, this transaction is just the very end of an interesting series of events. I had to start working my way backward to figure out how this was even possible,” smartcontracts tweets.
Guardians signed off a false transfer
Wormhole is a so-called bridge, a smart contract, on Ethereum in this case, that provides a way to move crypto assets between different blockchains. According to smartcontracts, from a high-level viewpoint, Wormhole specifically has a set of co-called guardians that sign off on transfers between the blockchains.
The Wormhole guardians had somehow signed off on this 80,000 ETH transfer as if it was 100% legitimate.
“The transaction that pulled out 80,000 ETH was actually the attacker transferring 80,000 ETH from Solana to Ethereum. I originally thought that the contract might have incorrectly validated the signatures on the transfer, but the signatures [were] completely checked out.”
According to smartcontracts, the first breakthrough and partial explanation came from a transaction on Solana which somehow minted 120,000 “Wormhole ETH”, wrapped ether on Solana, out of nowhere. Since the hacker was able to mint Wormhole ETH on Solana, he was able to correctly withdraw it back to Ethereum.
“Solana is kinda weird”
Examining the hacker’s transaction history, there’s a transaction that came right before the minting of the 120,000 Wormhole ETH. In this transaction, the hacker mints only 0.1 Wormhole ETH, as if the hacker was testing the function with a small amount.
A further examination of the hacker’s transaction history reveals that the hacker did make a deposit of 0.1 ETH from Ethereum into Solana. Though the attacker did not make an ETH deposit of 120,000 ETH into the Wormhole smart contract on Ethereum, there’s something interesting about this deposit.
As smartcontract explains in his tweet, the transactions that minted Wormhole ETH on Solana were triggering a Wormhole smart contract function called “complete_wrapped“. One of the parameters that this function takes is a “transfer message”, basically a message signed by the guardians of the bridge that says which token to mint and how much.
“Solana is kinda weird, so these parameters are actually smart contracts themselves. But the important thing is how these “transfer message” contracts get created. Here’s the transaction that made the 0.1 ETH transfer message,” smartcontracts tweets.
Who’s checking the checkers?
This “transfer message” contract is created by triggering a function called “post_vaa“. The most important thing is that post_vaa checks if the message is valid by checking the signatures from the guardians. That part seems reasonable enough, smartcontracts says, but it’s this signature checking step that broke everything.
The “post_vaa” function doesn’t actually check the signatures. Instead, in typical Solana fashion, there’s another smart contract that gets created by calling the “verify_signatures” function. One of the inputs to the “verify_signatures” function is a Solana built-in “system” program which contains various utilities the contract can use.
Within “verify_signatures”, the Wormhole program attempts to check that the execution that happened right before this function was triggered, was that the Secp256k1 signature verification function was executed.
“This verification function is a built-in tool that’s supposed to verify that the given signatures are correct. So the signature verification has been outsourced to this program. But here’s where the bug comes in,” smartcontracts tweets.
The Wormhole contracts used the function load_instruction_at to check that the Secp256k1 function was called first, but the load_instruction_at function was deprecated relatively recently because it does not check that it’s executing against the actual system address!
According to smartcontracts, the caller is supposed to provide as input the system address to the program being executed, but the hacker provided a different system address.
Here’s that system address being used as the input for the “verify_signatures” for the legitimate deposit of 0.1 ETH:
But here’s the “verify_signatures” transaction for the fake deposit of 120k ETH:
That’s not the system address!
“Using this “fake” system program, the attacker could effectively lie about the fact that the signature check program was executed. The signatures weren’t being checked at all!,” smartcontracts tweets.
“After that point, it was game over. The attacker made it look like the guardians had signed off on a 120k deposit into Wormhole on Solana, even though they hadn’t. All the attacker needed to do now was to make their “play” money real by withdrawing it back to Ethereum. And one withdrawal of 80k ETH + 10k ETH later (everything in the bridge on Ethereum), everything was gone.”