Alright. I figured out the Solana x Wormhole Bridge hack. ~300 million dollars worth of ETH drained out of the Wormhole Bridge on Ethereum. Here's how it happened.
Although it's dramatic, this transaction is just the very end of an interesting series of events. I had to start working my way backwards to figure out how this was even possible.
Wormhole is a "bridge" -- basically a way to move crypto assets between different blockchains. Specifically, Wormhole has a set of "guardians" that sign off on transfers between chains. It's a little more complicated than that in practice, but that's the general idea.
The transaction that pulled out 80k ETH was actually the attacker transferring 80k ETH from Solana to Ethereum. I originally thought that the contract might've incorrectly validated the signatures on the transfer, but the signatures completely checked out.
The Wormhole "guardians" had somehow signed off on this 80k ETH transfer as if it were 100% legit. How was that possible?
That explains part of it! The attacker was able to mint Wormhole ETH on Solana, so they were able to correctly withdraw it back to Ethereum. Now we just need to figure out how the attacker was able to mint this Wormhole ETH on Solana...
Of course, the attacker definitely did not make a 120k ETH deposit into Wormhole on Ethereum. But there's something interesting about this deposit. It definitely has something to do with the attack, but what?
Alright, here's where we start getting into the weeds of Solana. This is the first time I've ever looked at Solana contracts so it took me a while to get my bearings, but I think I finally get what's going on.
It doesn't really matter if you understand the fancy code, the most important thing here is that post_vaa checks if the message is valid by checking the signatures from the guardians. That part seems reasonable enough. But it's this signature checking step that broke everything.
One sec loading up my next tweets... hold your horses
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.
Here's that system address being used as the input for the "verify_signatures" for the legit 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!
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.
Wormhole reports that the exploit has been patched https://twitter.com/wormholecrypto/status/1489036273012682753?s=20&t=NLOh_IUNd6DlVWNAYUIIVA
It's interesting that this commit was made ~9 hours ago and the exploit happened a few hours after that. Possible that an attacker was keeping an eye on the repository and looking out for suspicious commits.
Could be that the Wormhole team spotted the bug, patched it, but the attacker got to it before the patch could be rolled out. Super important to keep these sort of patches lowkey and to try to stuff them into larger commits.
Not sure exactly what happened here, but a clear lesson to try to deploy before making any patch details public, if you can afford to do that. Of course this ends up being at odds with Web3 ideals, so not always clear how to best handle these sort of things.
As another commenter has noted, it could also be that the attacker knew about the bug in advance and was forced into exploiting the bug because the patch was being rolled out. Seems hard to construct this attack within ~2 hours so could be a possibility here.
You can follow @kelvinfichter.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: