In February 2022, Wormhole, a token bridge between Ethereum and Solana, was the victim of the second most expensive DeFi hack to date. The attacker exploited the use of a deprecated, insecure function to bypass signature verification and steal $326 million (120k wETH).
Inside the Attack
The actual extraction of 120k ETH from the Wormhole bridge came at the end of a series of events. The actual flow of the attack was:
- The attacker creates a validator action approval (VAA) with a call to post_vaa
- This VAA was used in a call to complete_wrapped to mint the 120,000 ETH extracted in the attack
- The attacker “legitimately” extracted the minted tokens from the bridge
The vulnerability that made the attack possible was a failure to perform proper signature verification in the VAA creation process. The role of signature verification is delegated several times from post_vaa to verify_signatures to Secp256k1.
The issue is that the Wormhole contract used a deprecated command called load_instruction_at to ensure that Secp256k1 was called previous to verify_signatures. However, this command doesn’t check the value of the system address, the Instructions sysvar.
The attacker created a fake version of the Instructions sysvar that was an account created previously that called the Secp256k1 contract. The attacker passed in this account rather than the Instructions sysvar. The check that Secp256k1 was called previously passed (even though it was in a completely different context), so the signatures were believed to have been properly verified. This created the valid SignatureSet needed to create the valid VAA, which was then used to mint the stolen ETH.
Lessons Learned From the Attack
The Wormhole hack was enabled by a chain of delegations of the signature verification. The developers’ use of a single, deprecated function (which doesn’t check addresses) enabled a forged signature pass without verification.
This hack demonstrates the importance of secure coding practices and an in-depth security audit for software security. The use of deprecated functions is poor code security and cost the project over $300 million.