$320 Million Wormhole Hack Explained
Credit: Khang Hoang, Giap Nguyen
Defi has been plagued by security issues. Wormhole hack is just another inevitable story.
In Feb 2,2022; an attacker exploited a security flaw to steal $320 million from the Wormhole Defi platform. It is the 4th largest crypto hack of all time.
The article explains the details of the hack and gives some thoughts about security of Solana and Defi.
What is the Wormhole?
The Wormhole is a Defi platform for exchanging messages between blockchains or a cross-chain message passing protocol. The platform helps moving digital assets such as tokens and NFTs between Ethereum, Solana, Terra, Binance Smart Chain, Polygon, Avalanche, và Oasis.
In a simple explanation, the Wormhole is a typical blockchain bridge:
To move N tokens from blockchain A to blockchain B. The token owner should lock N tokens into the bridge smart contract on blockchain A.
After verifying N tokens locked, the bridge mint N equivalent tokens (or wrapped tokens) on blockchain B.
To return N tokens. The token owner should burn N wrapped tokens on the bridge smart contract on blockchain B.
After verifying N wrapped tokens burnt, the bridge will release N tokens on blockchain A
In the real world, it looks like how the old US gold certificates work. After depositing gold bars, the US bank issues gold certificates equivalent in value. The certificate was transferable and anyone could redeem it back to gold. The bank should manage the security of gold storage and against counterfeit gold certificates.
Like the gold certificates system, blockchain bridges have two main security concerns:
Make sure locked tokens (gold bars) are safe.
Make sure wrapped tokens (gold certificates) are valid.
The short version of the $320m hack
In Feb 2, 2022; an attacker managed to bypass the Wormhole verification to mint 120,000 wrapped Eth tokens on the Solana network (without 120,000 Eth tokens locked on the Ethereum network). Then he used the invalid 93,750 wrapped Eth tokens to redeem back to equivalent Eth tokens on Ethereum network. The rest of invalid tokens are sold for SOL tokens.
It is the same with a bank where the customers hold $320m gold certificates but have no gold bars in their vaults.
The attacker’s wallets:
CxegPrfn2ge5dNiQberUrQJkHCcimeR4VXkeawcFBBka - on Solana 432,661.15 SOL ~51m USD
0x629e7da20197a5429d30da36e77d06cdf796b71a - on Ethereum 93,750 ETH ~287 m USD
The long version of the $320m hack
To understand the security incidents, we will brief the Solana programming model, the Wormhole programs, the root cause, and finally detail for the attack.
Brief of Solana programming model
An app interacts with the Solana network by sending transactions.
A Solana transaction have multiple tasks called instructions (other blockchain transactions is single task)
An Solana instruction invokes a Solana on-chain program with a list of Solana accounts as input and an extra opaque data.
A Solana on-chain program is equivalent to an Ethereum smart contract.
A Solana account is an on-chain state equivalent to an Ethereum address which could be an on-chain storage or a smart contract.
Because Solana accounts passing to programs as inputs, so they are untrustable. The Solana document recommended:
The Wormhole programs
There are 2 programs involved with the hack:
worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth - program guardian - source code
wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb - program token_bridge - source code
The program toke_bridge has a complete_wrapped function line 79 which performs minting wrapped tokens.
The complete_wrapped function require input #4: message_acc line 253. The message_acc stores a signed message which commands minting wrapped tokens.
The message_acc constructed by invoke function post_vaa from the guardian program
Function post_vaa validates the message (which contains a minting command) against signature_set then builds the message_acc for function complete_wrapped to perform the minting process.
The important signarture_set account line 189 grabbed from function verify_signatures
Notice the #4 input line 153 of the verify_signatures is a very special sysvar:instructions account.
The function verify_signatures requires the special sysvar:instructions account because it is supposed to work with a previous instruction.
A sample of Wormhole verify_signatures transaction have 2 instructions:
#1: call secp256k1 to extract signatures from the message
#2: call verify_signatures to verify the previous signatures and return the important signature_set.
To access the previous instruction data, the verify_signatures require the special sysvar:instructions account.
The sysvar accounts are populated by Solana runtime to provide runtime information. They are equivalent with Solidity global variables such as block.timestamp, msg.data or msg.sender.
The main difference is that in Ethereum those values are hardcoded and in Solana they are dynamically provided via input accounts. And Solana recommend programs must take responsibility to validate those accounts.
To summary Wormhole minting flow:
Call a transaction with 2 instructions: secp256k1 with minting message and guardian.verify_signature to build a valid signature_set.
Call guardian.post_vaa with valid signature_set and message to build a valid message_acc.
Call token_bridge.complete_wrapped with valid message_acc to mint wrapped token.
The root cause
It is clearly that the Wormhole developers forget to check #4 input of function verify_signatures is a real and valid sysvar:instructions account.
Solana developers also realize that it is a common and recurring problem. They updated Solana SDK to deprecate unsafe apis. The new apis automatically check sysvar account addresses.
Unfortunately, Wormhole developers did not update the critical verify_certificates function and leave the issue for the attacker to exploit.
This is the source code that contains the security flaw. Notice it used deprecated load_current_index line 92 and load_instruction_at line 101 against the input of sysvars:instructions account without checking it is a real one.
Image that the attacker read the deprecated notices from Solana SDK. He realized that it is a recurring issue. Performed a simple text search against Solana-based Defi source codes , he found the Wormhole security flaw and the rest is history.
For who don’t understand why Solana allow the critical sysvars accounts passing to programs as inputs. Well, it is because Solana program designed as stateless and functional.
Detail of the attack
The attacker created a malicious account 2tHS1cXX2h1KBEaadprqELJ6sV9wLoaSdX68FqsrrZRd
Call verify_certificates which replace #4 input account from sysvar:instructions to the malicious 2tHS1cXX2h1KBEaadprqELJ6sV9wLoaSdX68FqsrrZRd
Tx: 2SohoVoPDSdzgsGCgKQPByKQkLAXHrYmvtE7EEqwKi3qUBTGDDJ7DcfYS7YJC2f8xwKVVa6SFUpH5MZ5xcyn1BCK
Notice a normal Wormhole transaction requires 2 instructions: secp256k1 and verify_certicates. But the attack Wormhole transaction has single verify_certicates??? It is because the attack transaction controls the instruction data then it fakes all information even though there is no secp256k1 called.
At line 92, the fake 2tHS1cXX2h1KBEaadprqELJ6sV9wLoaSdX68FqsrrZRd account returns 1 even current_instuction is 0.
At line 101, the fake account returns the attack payload even though no secp256k1 called.
Call post_vva which valid signature_set EtMw1nQ4AQaH53RjYz3pRk12rrqWjcYjPDETphYJzmCX created from verify_certificates
2SohoVoPDSdzgsGCgKQPByKQkLAXHrYmvtE7EEqwKi3qUBTGDDJ7DcfYS7YJC2f8xwKVVa6SFUpH5MZ5xcyn1BCK
Complete minting wrapped eth by using message account GvAarWUV8khMLrTRouzBh3xSr8AeLDXxoKNJ6FgxGyg5 created by post_vva
2zCz2GgoSS68eNJENWrYB48dMM1zmH8SZkgYneVDv2G4gRsVfwu5rNXtK5BKFxn7fSqX9BvrBc1rdPAeBEcD6Es
.
The attackers used wrapped Eth to drain the Wormhole Eth pool. Remain wrapped Eth sole for SOL token to complete the hack.
Some thoughts about the hack
Solana is a young project and ecosystem. Expect more incidents in future unless serious security investment from the community.
Stop assigning normal developers to design and coding Defi smart-contracts. The typical practice of the DeFi industry is to have developers coding smart contracts and to have blockchain security providers review the final products. It is like a bank hiring a house contractor to build their gold vault. The best practice is hiring blockchain security developers to build the products and have other blockchain security vendors review and cross-check their works.
The main issue is lack of human resources in Defi security. The shift of security paradigm from centralized, server-side security to decentralized, client-side security is huge. It requires not only code-level security, but also overall design, code life-cycle, business logic and so on …