Логотип
Главная | Статьи | WebAssembly RE: декомпиляция и поиск уязвимостей в WASM
WebAssembly RE: декомпиляция и поиск уязвимостей в WASM

WebAssembly RE: декомпиляция и поиск уязвимостей в WASM

11 февраля, 2026

28

WebAssembly (WASM) – это не просто очередная игрушка для фронтенда. Это полноценный бинарник, который крутится в браузере и на серверах, и его можно эксплуатировать так же, как классические PE/ELF файлы. Только вот большинство исследователей безопасности до сих пор смотрят на WASM как на что-то экзотическое. А зря – уязвимости там есть, и они реальные.

Что такое WASM с точки зрения реверсера

WASM – это байткод, который компилируется из C/C++/Rust и других языков. У него два представления: бинарное (.wasm) и текстовое (.wat). Важный момент: WASM работает со своей линейной памятью, которая изолирована от основной памяти хоста, но это не значит, что её нельзя скоррапить.

Основные особенности, которые нужно знать:

  • Стековая виртуальная машина с типизированными инструкциями
  • Линейная память (массив байтов), которая может расширяться
  • Таблицы функций для непрямых вызовов
  • Импорты и экспорты для взаимодействия с JS или хостом

Инструментарий для декомпиляции

WABT – твой основной арсенал

WABT (WebAssembly Binary Toolkit) – это швейцарский нож для работы с WASM. Вот что тебе понадобится:​

wasm2wat – конвертирует бинарник в текстовое представление:

wasm-decompile – декомпилирует WASM в псевдокод, похожий на C/JS. Это твой лучший друг для быстрого анализа:​

Пример того, что получишь на выходе вместо ассемблерной каши:

wasm2c – декомпилирует WASM в валидный C-код, который можно скомпилировать обратно:​

wasm-objdump – дизассемблер с подробной информацией о секциях:

Ghidra и IDA Pro

Ghidra поддерживает WASM из коробки (с плагинами), а IDA Pro тоже можно прокачать под анализ WebAssembly. Это полезно, когда нужен граф потока управления (CFG) и глубокий статический анализ.

Техники реверсинга WASM

Шаг 1: Извлечение модуля

WASM может быть встроен прямо в JS или загружаться отдельным файлом. Открой DevTools → Network → фильтр по “wasm”. Или ищи WebAssembly.instantiate() в JS-коде.

Шаг 2: Базовый анализ структуры

Смотри на:

  • Imports – какие функции импортируются из хоста (часто это JS API)
  • Exports – что экспортирует модуль (точки входа для атаки)
  • Memory – размер и лимиты линейной памяти
  • Data section – статические данные (строки, константы, иногда хардкоженные ключи)
  • Table – таблица функций для непрямых вызовов​

Шаг 3: Декомпиляция

Ищи интересные функции – аутентификацию, криптографию, валидацию входных данных. В псевдокоде будет видно логику намного лучше, чем в .wat.​

Шаг 4: Анализ потока данных

WASM использует линейную память. Обращения к памяти выглядят так:

Прослеживай, откуда берутся значения для offset и base pointer – это ключ к поиску багов.

Типичные уязвимости в WASM

Buffer Overflow

Да, в WASM тоже есть переполнения буфера! Хотя WASM изолирован, скоррапленная память внутри модуля может привести к:

  • Перезаписи важных данных (флагов авторизации, токенов)
  • RCE через перезапись указателей функций в таблице
  • XSS через запись в DOM из скоррапленных данных

Пример уязвимого кода (C → WASM):

При компиляции в WASM это превращается в запись в линейную память без bounds check. Эксплуатация:

  1. Найди offset буфера в data section через wasm-objdump
  2. Перепиши данные после буфера (например, флаг admin=false → admin=true)
  3. Или перепиши entry в function table для перехвата контроля

Отсутствие Stack Smashing Protection (SSP)

В отличие от нативных бинарников, WASM часто компилируется без SSP. Это значит, что stack overflow эксплуатировать легче – нет канареек, которые надо обходить.​

Format String

Если WASM использует printf-подобные функции, format string bugs могут дать arbitrary read/write:

В WASM это можно использовать для чтения/записи в линейную память.

Use-After-Free и Integer Overflow

Работают так же, как в нативном коде. UAF особенно опасен, если WASM управляет объектами JS через импортированные функции.

Improper Validation of Array Index

Можно читать/писать за пределами массива в линейной памяти.

Redirecting Indirect Calls

WASM использует таблицы функций для непрямых вызовов. Если можешь контролировать индекс в таблице, получаешь call hijacking:

Перепиши $func_index и вызовешь любую функцию из таблицы.

Практика: эксплуатация BOF в WASM

Реальный сценарий из исследований:

  1. Reconnaissance: Декомпилируем модуль и находим функцию логина
  1. Vulnerability: Обнаружена strcpy без проверки длины, пароль хранится в памяти по offset 1024
  2. Exploitation:
  1. Result: Получаем arbitrary write, перезаписываем флаг авторизации или токен.

Продвинутые техники

Символьное выполнение с Manticore

Manticore поддерживает WASM для автоматического поиска уязвимостей:

Fuzzing WASM модулей

Используй wasm-interp из WABT для запуска модуля с фаззинговыми входами:

Динамическая инструментация

Патчи WASM байткод на лету для логирования или изменения поведения:

Deobfuscation

Обфусцированный WASM часто использует:

  • Мёртвый код (dead code)
  • Запутанный control flow
  • Encrypted strings

Лайфхак: используй wasm-decompile и затем прогони через оптимизатор:

Лайфхаки и советы

  1. Мониторинг памяти: Патчи браузерные WASM API для логирования всех memory.grow() вызовов – увидишь, как модуль работает с памятью в рантайме.
  2. Поиск секретов: Data section часто содержит хардкоженные ключи API, пароли:

3. Function table mapping: Экспортируй таблицу функций и сопоставь с именами из debug info (если есть):

  1. Bypass validation: Если WASM валидирует входные данные, попробуй модифицировать модуль с помощью wasm-opt или патчинга байткода напрямую.
  2. Runtime hooking: Используй Frida для hooking WASM функций в браузере:
  1. CVE hunting: Следи за уязвимостями в WASM runtime (Wasmtime, Wasmer) – часто они позволяют сбежать из sandbox.

Bottom Line

WASM – это полноценная цель для реверс-инжиниринга и эксплуатации. Инструменты есть, уязвимости реальные, а исследователей мало. WABT даёт всё необходимое для статического анализа, Manticore – для символьного, а комбинация декомпиляции + динамического анализа позволяет находить баги, которые пропускают стандартные инструменты.

Главное – не забывай, что линейная память WASM – это просто буфер, а баги работы с памятью никуда не делись. Ищи overflow, format strings, UAF – и найдёшь. Удачной охоты!