Уразливості децентралізованої біржі

За минулий місяць збитки в результаті хакерських атак на криптоспільноту зросли до $1.019 млрд (24.10), перевищивши показники минулих місяців (без урахування інциденту Terra Luna).

Придивившись ближче, ми можемо побачити, що основні експлойти були здійснені на платформах DEX (децентралізована біржа), підсумовуючи майже 15% загальних втрат лише в жовтні.

Маючи це на увазі, давайте глибше зануримося в три випадки у світі експлуатації DEX і спробуємо відповісти на ці запитання:

  • Які основні причини вразливості DEX?
  • Як ми можемо уникнути цього в майбутньому?

Обмін бананами

28 серпня біржа токенів $DDC, Обмін бананами, піддався нападу. Зловмисник успішно маніпулював ціною монети, зламавши внутрішню логіку розрахунку ціни, і в результаті обміняв 23 $DDC на 110,105 XNUMX $BUSD.

Уразливість була досить простою, але вплив мав величезний потенціал прибутку:

  1. Атака почалася з транзакції в розмірі 26 $DDC на рахунок зловмисника
  2. Потім було розпочато пошук гаманця жертви, щоб знайти гаманець, який містить велику кількість токенів
  3. [Експлуатація] Коли відповідний обліковий запис було знайдено, зловмисник подзвонив handleDeductFee який виконував а списання майже всіх жетонів з балансу жертви
  4. Щоб завершити маніпулювання цінами, функція sync було викликано для оновлення значення/ціни $DDC

У результаті баланс $DDC у пулі зменшився до 0.0003 $DDC, після оновлення вартості/ціни ціна $USD, що відповідає $DDC, значно підвищується, і велику суму $USD можна обміняти через невелику суму $DDC. Хакер використав 23 $DDC для обміну на 104,600 XNUMX USD.

Тож як зловмиснику вдалося маніпулювати балансом рахунку жертви? Що було handleDeductFee виконання функції?

Давайте подивимося на код:

function handleDeductFee (ActionType actionType, uint256 feeAmount, address from, address user) external override {
	distributeFee(actionType, feeAmount, from, user);
}
// deduct the config fee and transfer to handle fee address which config.
// parameter from
function distributeFee (ActionType actionType, uint feeAmount, address from, address user) internal { 
	_balances [from] = _balances[from].sub(feeAmount);
	...
}

Тут ми маємо зовнішню функцію з керованими аргументами, яка викликає внутрішню функцію, передаючи ті самі аргументи як параметри, яка виконує дедукцію, використовуючи ці аргументи одразу.

Зловмисник передав адресу жертви як свою from параметр і feeAmount було трохи менше, ніж результат balanceOf цієї адреси.

Це воно! Жодної перевірки вхідних даних. За цим взагалі немає складної теорії.

Кібер Безпека 101: Ніколи не довіряйте даним, які контролює користувач.

Більше інформації можна знайти в публікації Beosin Alert у Twitter тут.

Далі ми розглянемо більш складний протокол. Але, як ми вже бачили, відсутність одного рядка коду може зламати всю систему.

Транзитний обмін

Транзитний обмін це багатоланцюгова платформа-агрегатор DEX, що працює на мережах Ethereum і Binance. 1 жовтня платформа стала жертвою атаки, під час якої з гаманців користувачів протоколу було витягнуто активів на суму майже 29 мільйонів доларів.

Обмін за допомогою Transit Swap включає проходження кількох контрактів, які направляють і з’єднують різні обмінники та забезпечують керування дозволами. Кожен із контрактів викликає інший, передаючи свої параметри як аргументи наступному, кожен із них використовує параметри для обробки певної логіки та виконання дій.

Спрощена версія потоку даних виглядає приблизно так:

Як я вже згадував раніше, кожен із контрактів викликає наступну передачу аргументів як параметрів, тож чому це так критично?

«Основна причина цієї атаки полягає в тому, що протокол Transit Swap не перевіряє строго дані, передані користувачем під час обміну маркерами, що призводить до довільного зовнішнього виклику». – Аналіз SlowMist

Жоден із контрактів належним чином не підтверджував дані, використані для здійснення транзакції. У результаті зловмисник успішно маніпулював усім ланцюжком, передаючи спеціально створені дані для кожного кроку транзакції.

Це ще один випадок перевірки даних із більшою вразливістю. Давайте перейдемо до однієї з найбільших втрат цього року:

Майар Біржа – Елронд Мережа

Третя найприбутковіша атака DEX за весь час була проведена на Майар DEX. Хакери використали вразливу функцію, нещодавно розгорнуту в основній мережі. Вони успішно спустошили резерви протоколу, викравши активи на 113 мільйонів доларів.

Експлойт почався з функції executeOnDestByCaller що дозволило контракту A виконувати дії з контрактом C через проксі B. Контракт A викличе функцію всередині B, яка дозволяє B виконувати дії з C від імені контракту A.

Щоб проілюструвати це, ми проілюструємо контракти A, B і C. Виклики контракту A foo що всередині Б. foo дзвінки executeOnDestByCaller що дозволяє B виконувати функцію bar Контракту C як самозванець A.

На практиці контракт B може виконувати будь-яку функцію від імені A, якщо A зробив перший виклик B. Ця ідея вже звучить трохи дивно.

Щоб створити експлойт за допомогою цієї функції, потрібно з’ясувати, як змусити жертву викликати контракт, а потім можна робити з цим контрактом що завгодно, використовуючи зовнішні функції, які він надає, як-от transferFrom.

На щастя для хакерів, у Елронда є концепція під назвою Зворотні дзвінки. Використовуючи ці зворотні виклики, можна передати шкідливу функцію як зворотний виклик жертві, у якої не буде іншого виходу, окрім як виконати зворотний виклик, а решта залишиться в історії.

Якщо ви хочете зануритися глибше, зверніться до Офіційний звіт Елронда та Зрив атаки Арда.

Отже, у коді не було вразливості, а скоріше логічна помилка. Громадськість виявила численні проблеми безпеки з цією функцією після розгортання, але патч і виправлення могли бути доставлені лише через тиждень, таким чином піддаючи всі контракти потенційній вразливості протягом цілого повного тижня.

Відповіді на запитання

Знаючи те, що ми знаємо зараз, ми можемо відповісти на ці запитання.

Обговорювані інциденти мають спільну причину: вразливість смарт-контракту. Ми всі знайомі з термінами «вразливості» та «експлойти» в інших сценаріях, тож чим це відрізняється від сценарію смарт-контракту?

  1. Відкритий вихідний код – як ми всі знаємо, «D» у DEX означає децентралізований, що означає, що продуктом керують користувачі, і це робить код доступним для всього світу. Це полегшує пошук вразливостей.
  2. Важко оновити – вартість пошуку та оновлення вразливості набагато вища, ніж у додатку поза мережею. Оскільки контракти завантажуються в ланцюг, виправлення вразливості означає завантаження нової копії контракту та перенаправлення всіх адрес зі старої на нову, якщо проксі-контракт не використовується.

Тому ми не отримуємо другого шансу. Ми повинні переконатися, що контракт вільний від помилок і безпечний, перш ніж завантажувати його в мережу.

Аудит безпеки перед завантаженням і постійний моніторинг загроз безпеці є ключовими заходами в світі децентралізованих програм.

Висновок

Ці приклади охоплюють лише частину вразливостей і проблем, виявлених у смарт-контрактах. У міру розвитку Web 3 у світі будуть представлені більш складні алгоритми, алгоритми, які можуть зіграти важливу роль у наступному експлойті та призвести до втрат коштів.

Аналіз минулих експлойтів і пом’якшення, аудит і перевірка коду можуть запобігти втратам коштів і мати величезне значення для майбутнього децентралізованих програм.

Написане
Ітай Чередман

Ітай є дослідником безпеки в Sayfer. Він захоплений розумінням і дослідженням векторів атаки та захисту, які з’являються в нових технологіях.

Перейти до вмісту