Wormhole Bridge Hack: технічний аналіз експлоїту $326M

Article author

Взлом моста Wormhole: Технічний аналіз експлойту на $326 млн

2 лютого 2022 року токен-міст Wormhole втратив 120 000 wETH — приблизно $326 мільйонів на той час — у одній з найбільших атак на смарт-контракти в історії DeFi. Для атаки не були потрібні вкрадені ключі, соціальна інженерія чи контроль більшості мережі валідаторів Guardian. Потрібна була одна річ: застарілий API програми Solana, яка не перевіряла, з якого саме акаунта вона читає дані.

Розуміння цього експлойту є необхідним для кожної команди, що працює на Solana, для кожного протоколу, який покладається на крос-чейн повідомлення, і для кожного аудитора, що перевіряє програми Solana. Корінною причиною була помилка перевірки смарт-контракту в програмі мосту Wormhole на Solana — а не компрометація ключів чи збій мережі Guardian. Ключі Guardian залишилися недоторканими. Власний код мосту надав зловмиснику авторизацію, якої той ніколи не мав отримати.

Яка була основна технічна вразливість у зломі Wormhole?

Вразливість містилась у інструкції verify_signatures програми Wormhole на Solana (bridge.so). Ця функція відповідала за перевірку, що акаунт SignatureSet — що містить підписи Ed25519 або Secp256k1 від вузлів Guardian — справді відображав консенсус перед авторизацією Verifiable Action Approval (VAA).

Проблема полягала в тому, що verify_signatures використовував застарілу функцію solana_program::sysvar::instructions::load_instruction_at для перевірки того, що інструкція попередньої перевірки Secp256k1 була викликана раніше в тій же транзакції. Застарілий варіант не перевіряє, чи є акаунт, що передається, фактичною системною змінною інструкцій Solana (Sysvar1nstructions1111111111111111111111111). Він читає з будь-якого акаунта, що стоїть на вказаному індексі, включно з повністю контрольованим атакуючим акаунтом.

Отже, зловмисник міг передати сфабрикований акаунт, що імітує структуру системної змінної інструкцій, попередньо заповнений підписами, контрольованими атакуючим, над обраним зловмисником payload. Функція читала фейкові дані, знаходила виклик Secp256k1 “присутнім” (у зовсім іншому контексті), позначала VAA як схвалений Guardian та повертала успішний результат.

Із фальсифікованим підтвердженим VAA атакуючий викликав complete_wrapped, яка довіряла статусу схвалення VAA мостової програми для авторизації емісії wrapped-активів на Solana. Результат: 120 000 wETH емісовано без відповідного блокування ETH на Ethereum.

Виправлення — заміна load_instruction_at на load_instruction_at_checked, яка накладає верифікацію, що акаунт справді є системною змінною інструкцій — було додано в репозиторій Wormhole на GitHub до атаки, але ще не розгорнуто на mainnet.

Фактор Опис Вплив
Застарілий API sysvar load_instruction_at без варіанту _checked; відсутність перевірки власника акаунта на вказаному індексі Атакуючий може подати підроблений акаунт інструкцій замість справжньої системної змінної інструкцій
Обхід verify_signatures Функція приймала виготовлений атакуючим акаунт SignatureSet як доказ консенсусу Guardian без перевірки походження акаунта Авторизація емісії надана без жодних реальних підписів Guardian
Відсутність перевірки власника акаунта Акаунт SignatureSet не перевірявся, чи належить програмі системної змінної інструкцій (Sysvar1nstructions11...) Відсутність цієї перевірки — фундамент усієї вразливості
Право емісії wrapped-активів Програма мосту Solana мала необмежене право емісії wrapped-токенів; авторизація потребувала лише схваленого VAA 120 000 wETH емісовано на Solana без блокування ETH на Ethereum; приблизно $326 млн на момент атаки

Чем відрізнявся злом Wormhole від інших атак на мости, наприклад Ronin?

Злом мосту Ronin (березень 2022, близько $625 млн) часто порівнюють із Wormhole у дискусіях про безпеку мостів. Це принципово різні типи збоїв.

Wormhole був помилкою перевірки смарт-контракту в програмі мосту на Solana. Мережа Guardian — порігова схема підписів із 19 вузлів — не була скомпрометована. Зловмисник обійшов її повністю, скориставшись тим, що verify_signatures ніколи не перевіряв, з якого акаунта він зчитує. Ключі Guardian були недоторкані, мережа працювала, але це було марним: код ніколи не звертався до справжнього консенсусу Guardian.

Ronin — це була крадіжка операційних ключів. Sky Mavis оперувала п’ятьма з дев’яти валідаторів Ronin. У листопаді 2021 Axie DAO тимчасово делегувала права підписання Sky Mavis для розвантаження транзакцій. Делегація так і не була відкликана після завершення терміну. Зловмисник — пізніше приписаний Lazarus Group — зламав внутрішні системи Sky Mavis і отримав доступ до чотирьох ключів валідаторів Sky Mavis. Використовуючи активну делегацію Axie DAO, він отримав п’ятий підпис через безплатний RPC-вузол Sky Mavis. Маючи п’ять з дев’яти дійсних підписів, зловмисник подав легальні повідомлення на зняття коштів до контракту моста Ronin. Помилки смарт-контракту не було. Міст зробив те, для чого його створили, — авторизував зняття на основі п’яти легітимних підписів валідаторів.

Wormhole (лютий 2022) Ronin (березень 2022)
Вектор атаки Обхід перевірки акаунта в програмі Solana Соціальна інженерія і компрометація облікових даних вузлів Sky Mavis
Метод експлойту Підроблений акаунт SignatureSet через застарілий API sysvar Легітимні підписані зняття із викраденими ключами валідаторів
Мережа Guardian / валідаторів Повністю ціла; обійдена кодом, а не атакуючим Скомпрометована — атакуючий володів 5 із 9 ключів валідаторів
Методи впливу Несанкціонована емісія на Solana без блокування ETH на Ethereum Пряме зняття з контракту Ronin через дійсні підписи
Вкрадена сума ~ $326 млн (120 000 wETH) ~ $625 млн (173 600 ETH + 25,5 млн USDC)
Висновок з безпеки Перевірка власника акаунта є обов’язковою в програмах Solana; порогові підписи працюють лише якщо міст справді їх використовує Порогові схеми підписів не захищають від компрометації більшості ключів; відкликання делегацій має контролюватися

Покроковий опис, як відбувся експлойт Wormhole

  1. Підробка акаунта. Атакуючий створив акаунт Solana, що імітував структуру, очікувану на позиції SignatureSet у даних інструкції моста Wormhole. Цей акаунт містив підписи, контрольовані атакуючим — дійсні підписи Ed25519/Secp256k1, але над payload, який дозволяв емісію 120 000 wETH на адресу атакуючого на Solana.

  2. Обхід через застарілий API sysvar. Атакуючий подав транзакцію, що викликала verify_signatures у програмі моста Wormhole на Solana. Програма викликала load_instruction_at — застарілий варіант без перевірки — щоб підтвердити виклик інструкції Secp256k1 ранiше в тій же транзакції. load_instruction_at читає акаунт на вказаному індексі, не перевіряючи, чи є він справжньою системною змінною інструкцій (Sysvar1nstructions1111111111111111111111111).

  3. Прийняття підробленого доказу. verify_signatures прочитав підписи з акаунта атакуючого, визнав їх криптографічно дійсними (адже атакуючий підписав їх сам, над своїм payload), і позначив VAA як схвалений Guardian. Мережа Guardian не була запрошена.

  4. Авторизація емісії. Атакуючий викликав complete_wrapped з тепер уже схваленим VAA. Програма мосту, довіряючи статусу авторизації VAA, емісувала 120 000 wETH на Solana на адресу атакуючого.

  5. Виведення через крос-чейн. Зловмисник провів minted wETH назад на Ethereum через легітимний крос-чейн потік Wormhole — оскільки wETH були в гаманці атакуючого на Solana, міст обробив це як звичайний трансфер. $326 млн несправжнього wETH опинилися на Ethereum, де атакуючий конвертував їх у ETH та стейблкоїни й вивів кошти. Батьківська компанія Wormhole, Jump Crypto, відшкодувала вкрадені 120 000 ETH зі своїх резервів, щоб компенсувати користувачів мосту.

Найважливіші технічні уроки для програм Solana та крос-чейн мостів

1. Кожен AccountInfo, переданий програмі Solana, контролюється атакуючим, доки не доведено протилежне.

Це фундаментальне правило безпеки програм Solana. Програма має перевіряти поля owner, key і — за потреби — executable і is_signer кожного отриманого акаунта. Застаріла функція load_instruction_at приймала будь-який акаунт, розміщений на вказаному індексі. Сучасний аналог load_instruction_at_checked накладає перевірку, що акаунт справді є системною змінною інструкцій, перед читанням. Методологія аудиту Soken позначає використання не-_checked варіантів sysvar API як критичну вразливість, незалежно від контексту.

2. Розмежування привілеїв між перевіркою підписів і емісією активів.

Право емісії мосту має бути захищене модулем перевірки, який повторно виводить доказ із канонічного стану підконтрольного програмі, а не з акаунтів, поданих викликачем. Коли verify_signatures приймав атакуючий акаунт як джерело істини, розмежування між «чи схвалила мережа?» і «чи можемо емісувати?» повністю зникло. Інструкція емісії має отримувати авторизацію зі стану, який програма сама записала після перевірки справжнього вводу від Guardian.

3. Захист від повторного використання VAA має виконуватись on-chain.

Навіть якби SignatureSet був автентичним, complete_wrapped мала відхиляти VAA, хеш яких уже було використано. Wormhole додав захист від повторів у пізніших версіях, але в експлуатованій версії відсутність цього означала, що підтасований VAA можна було повторно застосовувати необмежено. Кожна дія мосту має бути прив’язана до мапи спожитих VAA (processed_vaas: mapping[bytes32, bool]), що оновлюється атомарно на старті виконання.

4. Використання застарілих API — критична знахідка аудиту.

Вразливість Wormhole була відомою через застарілість. Solana SDK позначила load_instruction_at як застарілу та запропонувала _checked заміну до атаки. Відсутність міграції з застарілого API — це не питання якості коду, а критична пролом у безпеці, яку атакуючі активно шукають, аналізуючи changelogs і порівнюючи не розгорнуті коміти з деплойнутим байткодом. Аудити Solana-програм мають ретельно перевіряти використання solana_program::sysvar::instructions::* на наявність не-_checked варіантів і критично блокувати їх. Це стандартна практика у пост-2022 аудитах від Ottersec, Halborn і Soken.

5. Нерозгорнуті виправлення безпеки — це публічна карта атаки.

Виправлення load_instruction_at_checked було додано в публічний репозиторій Wormhole до атаки. Вишуканий атакуючий, який слідкує за репозиторіями цільових протоколів, особливо за комітами з безпековими патчами та заміною застарілих API на їх checked аналоги, може реконструювати вразливість лише за diff. Канали розгортання програм із критичною безпекою мають вважати проміжок між «мерджем у main» та «деплоєм на mainnet» активним вікном експозиції. Процедури екстреного деплою повинні закривати це вікно за години, а не за дні.

6. Пороговий мульти-сіг не компенсує відсутність валідації акаунтів.

Мережа Guardian Wormhole складалася з 19 незалежних вузлів із пороговою схемою підписів. Вона була надійною. Вона була повністю непричетна до цієї атаки. Експлойт оминув весь рівень консенсусу, маніпулюючи акаунтом, який зчитував verify_signatures. Порогові підписи захищають від компрометації ключів Guardian, але не захищають від помилки, коли код узагалі не питає їхню думку. Захист у глибину потребує, щоб кожен рівень безпеки справді застосовувався — оминений контроль перестає бути контролем.

Що це означає для аудитів мостів і безпеки програм Solana

Експлойт Wormhole демонструє, що безпека крос-чейн мостів — це багаторівневе питання. Мережа Guardian може бути криптографічно надійною, економічні стимули правильно вирівняними, архітектура протоколу — відмінною — і все це нівелює один застарілий виклик функції в ончейн-програмі.

Для команд, що працюють на Solana, урок валідації акаунтів загальний: вважайте кожен параметр, переданий до вашої програми, як ворожий ввід. Перевіряйте власника, ключ, розпізнавач і довжину даних перед операцією з будь-яким акаунтом. Використовуйте обгортку Account<T> з фреймворку anchor або аналогічний механізм для забезпечення цих перевірок на рівні типів замість ручних асерцій.

Для архітекторів мостів урок — це розмежування привілеїв і прив’язка до канонічного стану. Право емісії має походити зі стану, що записаний і перевірений самою програмою, а не з доказів, наданих викликачем і прийнятих без перевірки програмою.

Soken аудитує кожну програму Solana на використання застарілих sysvar API, відсутність перевірок власника акаунта і прогалини захисту від повторного використання VAA як критичні проблеми. Патерн Wormhole — оминання порогового мульти-сігу шляхом маніпулювання акаунтом, який зчитує функція перевірки — тепер є визначеним класом атак у нашій методології аудиту Solana. Якщо ваш протокол використовує крос-чейн повідомлення або емісію wrapped-активів, зв’яжіться з нами за адресою soken.dev/services-it.html, щоб обговорити безпековий огляд перед розгортанням.

Article author

Frequently Asked Questions

Яка була основна причина зламу Wormhole bridge?

Злом стався через застарілий Solana API (`load_instruction_at` без `_checked`) у функції `verify_signatures`, яка не перевіряла, що читаний акаунт був дійсним sysvar інструкцій. Атакувальник подавав сфальшований акаунт із самопідписаними підписами, що дозволило обходити Guardian consensus та випускати ненадійні wETH.

Чи були скомпрометовані ключі валідаторів Wormhole Guardian?

Ні, схема підписів 19 вузлів Guardian залишилася непорушною. Експлойт обійшов її, маніпулюючи акаунтом, з якого `verify_signatures` читав дані — контракт фактично не звертався до Guardians.

Чим відрізнявся злам Wormhole від атаки на Ronin bridge?

Wormhole — це баг у перевірці смарт-контракту на Solana, ключі не крали. Ronin — крадіжка операційних ключів через соціальний інжиніринг, де викрали 5 із 9 ключів валідаторів Sky Mavis і підписували legit withdrawal messages.

Як Solana програми можуть запобігти таким атакам?

Слід ретельно перевіряти кожний AccountInfo параметр: власника, ключ та executable flags перед роботою. Використовувати `load_instruction_at_checked` або обгортку Anchor Account, які забезпечують перевірку sysvar на рівні типів. Вважати виклики sysvar без _checked критичними для аудиту.

Які практики аудиту виявляють цю проблему зараз?

Сучасні аудити Solana програм аналізують використання `solana_program::sysvar::instructions::*` на нелегітимні варіанти без _checked і відхиляють знайдені. Також перевіряють захист від повторного запуску VAA, чітке розділення привілеїв верифікації доказів та авторизації емісії, а також швидке впровадження оновлень безпеки.

Чат