samczsun Profile picture
Feb 3 15 tweets 7 min read
How did the @wormholecrypto exploit work? I joined forces with @gf_256 and @ret2jazzy to reverse engineer the exploit, and now that it's been patched we can finally share it with you👇 Image
First, we had to determine where the exploit occurred. Ethereum, or Solana? A quick check of the encoded VM that the attacker submitted showed that it contained valid signatures from the guardians. This meant that either they got the private keys, or they exploited the bridge. Image
Given that the attackers had left over $600MM in tokens in the bridge, I figured that the latter was more likely. Sure enough, there was a corresponding transaction on Solana where the attacker bridged out the ETH.

solscan.io/tx/5UaqPus91wv… Image
But how did the attacker get 120,000 ETH in the first place? That would be from this earlier transaction.

solscan.io/tx/2zCz2GgSoSS… Image
So what was going on in that transaction? We checked Wormhole's GitHub and determined that they must have called the `complete_wrapped` function. ImageImage
But the `complete_wrapped` function requires a valid VAA. How did the attacker generate a VAA account that the bridge would accept? When we checked the VAA account that the attacker used, we found that it had been created in an even earlier transaction.
Specifically, in this transaction, the attacker called `post_vaa` on the main Wormhole bridge.

solscan.io/tx/2SohoVoPDSd… ImageImage
So now we needed to figure out how the attacker managed to bypass the signature checks that `post_vaa` performs. Image
Well, the attacker provided a `SignatureSet` which was created in yet another transaction. This one called `verify_signatures` on the main bridge.

solscan.io/tx/25Zu1L2Q9uk… ImageImage
The `verify_signatures` function is meant to take a set of signatures provided by the guardians and pack it into a `SignatureSet`. But it doesn't actually do any of the verification itself. Instead, it delegates that to the Secp256k1 program. Image
And herein lies the problem. The `solana_program::sysvar::instructions` mod is meant to be used with the Instructions sysvar, a sort of precompile on Solana. However, the version of `solana_program` that Wormhole used didn't verify the address being used. ImageImage
This meant that you could create your own account which stored the same data that the Instructions sysvar would have stored, and substituted that account for the Instruction sysvar in the call to `verify_signatures`. This would essentially bypass signature validation entirely.
Sure enough, that's exactly what the attacker did. Hours earlier, they created this account which contained a single serialized instruction corresponding to a call to the Secp256k1 contract. Then they passed in that account as the Instruction sysvar.

solscan.io/account/2tHS1c… ImageImage
Once they had the fake `SignatureSet`, it was trivial to use it to generate a valid VAA and trigger an unauthorized mint to their own account. The rest is history.
tl;dr - Wormhole didn't properly validate all input accounts, which allowed the attacker to spoof guardian signatures and mint 120,000 ETH on Solana, of which they bridged 93,750 back to Ethereum.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with samczsun

samczsun Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(