Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-15718-who-put-ptrs-in-my-wasm — Цепочка эксплойта PoC для CVE-2026-15718: компилятор базового уровня wasm в SpiderMonkey, отсутствие синхронизации в array.fill -> недопустимый указатель -> addrOf/fakeobj -> произвольное чтение/запись -> RCE | Kitploit
Инструменты/GitHubGitHub/sneakynachos/cve-2026-15718-who-put-ptrs-in-my-wasm
Анализ уязвимостейЭксплуатацияОбратная инженерияВеб-безопасностьРазработка Полезной НагрузкиЭксплуатация Бинарных Файлов
GitHubsneakynachos/cve-2026-15718-who-put-ptrs-in-my-wasm

CVE-2026-15718-who-put-ptrs-in-my-wasm

Цепочка эксплойта PoC для CVE-2026-15718: компилятор базового уровня wasm в SpiderMonkey, отсутствие синхронизации в array.fill -> недопустимый указатель -> addrOf/fakeobj -> произвольное чтение/запись -> RCE

Репозиторий
11 день назадЕщё не проверено

Популярное

Смотреть все →

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

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-15718 — кто положил указатели в мой wasm

Цепочка эксплойта уровня proof-of-concept для CVE-2026-15718 — ошибочная компиляция из-за пропущенного sync() в базовом компиляторе WebAssembly движка Mozilla SpiderMonkey (компонент «JavaScript: WebAssembly»). Один-единственный array.fill с нулевым числом итераций даёт примитив fakeobj; цепочка развивается до произвольного чтения/записи в процессе хоста и выполнения произвольного нативного кода (posix_spawnp("/bin/sh", ...)).

  • CVE: CVE-2026-15718 (CWE-763, освобождение недопустимого указателя)
  • Затронуты: Firefox < 152.0.6, Firefox ESR < 140.13, Thunderbird < 140.13
  • Исправлено в: Firefox 152.0.6 / ESR 140.13 / Thunderbird 140.13, 2026-07-14
  • Апстрим-баг: Mozilla Bug 2045443 (MFSA-2026-67)
  • Исправляющий коммит: 4441102e62e8 («Bug 2045443», одна строка)

Первопричина

BaseCompiler::emitArrayFill() () генерирует цикл заполнения , не вызывая предварительно :

js/src/wasm/WasmBaselineCompile.cpp
array.fill
sync()
root@kitploit:~
   if (elementType.isRefRepr()) {
     freePtr(RegPtr(PreBarrierReg));
   }

+  sync();
+
   // Perform the fill loop using `numElements` as the loop variable ...

sync() сбрасывает стек значений базового компилятора (stk_) из регистров в машинный стек. Вызываемая на каждой итерации цикла заполнения неточная пост-барьерная проверка (emitPostBarrierEdgeImprecise) вызывает sync() внутри себя — но только если цикл выполняется. Метка выхода из цикла (done) является точкой соединения двух путей:

  • цикл выполнился хотя бы один раз (элементы reftype): stk_ синхронизирован — каждый операнд находится в слоте машинного стека;
  • нулевая итерация (numElements == 0): stk_ не тронут — операнды по-прежнему живут только в регистрах.

Статическая модель компилятора после точки соединения всегда отражает синхронизированный путь, поэтому код, сгенерированный после array.fill, читает операнды из стековых слотов, которые при нулевой итерации никогда не записывались. Операнд типа reftype, прочитанный таким образом, является недопустимым (устаревшим) указателем (CWE-763).

Примитив: техника «plant/read» слотов

Рассинхронизация двунаправленная между двумя wasm-функциями с одинаковыми фреймами:

  • plant (n = 1, цикл выполняется): sync() внутри цикла записывает значение в слот — настоящий ref (addrOf) или контролируемый i64 (подготовка fakeobj);
  • read (n = 0, нулевая итерация): слот никогда не записывается; функция-близнец читает устаревший слот — как i64 (утечка) или как (ref $t) (fakeobj).

Цепочка эксплойта (poc/)

FileStageResult
poc-min.js (+ gen_trigger.py)демо рассинхронизацииконтролируемый путь возвращает корректное значение; путь с нулевой итерацией возвращает мусорный указатель, прочитанный из никогда не записывавшегося слота
chain.js (+ gen_chain.py, chain.tpl.js, build.sh)полная цепочкаaddrOf + fakeobj → поддельный WasmArrayObject → произвольное R/W → утечка базового адреса XUL → обход импортов Mach-O в рантайме → подделанный funcref → posix_spawnp("/bin/sh", ["-c", "touch /tmp/CVE-2026-15718-PWNED"])

Детали этапов в chain.js:

  1. plantSpray/plantCmd/plantFun/plantExt + leak — addrOf для wasm-массивов, funcref-ов и JS-объектов (externref).
  2. sprayV + fakeRd/fakeWr — fakeobj; поддельный WasmArrayObject (numElements_ @+16, data_ @+24, инлайн-элементы @+40), при этом поддельное окно хранится во внешнем (malloc'd) массиве, чтобы GC не мог переместить его во время сканирования.
  3. Утечка нативного входа JSFunction (+0x20), обратное постраничное сканирование в поисках магического числа Mach-O (0xfeedfacf) → базовый адрес XUL.
  4. Полностью динамическое разрешение символов: обход load-команд Mach-O в XUL через произвольное чтение (LC_SEGMENT_64/LC_SYMTAB/LC_DYSYMTAB + таблица косвенных символов) для поиска записи _posix_spawnp в секции __stubs. Никаких захардкоженных смещений; стаб выполняет ленивое связывание при первом вызове.
  5. Создаём поддельный funcref (typeDef @+0x40 скопирован из настоящего ref.func, цель вызова @+0x38 = адрес стаба) и вызываем его через call_ref с posix_spawnp(pid, "/bin/sh", 0, 0, [sh, -c, cmd], 0).

Запуск

Протестировано с xpcshell (или оболочкой js / браузером), собранным из дерева до 152.0.6 (в качестве эталонной сборки здесь используется Firefox 149.0a1, 2026-01-14):

root@kitploit:~
# minimal desync demo
xpcshell poc/poc-min.js

# full chain (regenerates chain.js from the template + generator)
(cd poc && sh build.sh)
rm -f /tmp/CVE-2026-15718-PWNED
xpcshell poc/chain.js    # creates /tmp/CVE-2026-15718-PWNED
ls -l /tmp/CVE-2026-15718-PWNED

Харнесс устанавливает javascript.options.wasm_optimizingjit=false, чтобы зафиксировать базовый тир во время длительного сканирования Mach-O (баг присутствует только в базовом компиляторе; в браузере триггер срабатывает задолго до порога повышения тира, так что там это не требуется). tools/xul_slots.py — офлайн-валидатор, который перечисляет именованные слоты стабов/GOT в XUL (используется для перекрёстной проверки рантайм-обходчика).

Заметки о переносимости

Смещения приведены для macOS arm64, именно этого дерева/сборки (WasmArrayObject { +16 numElements, +24 data_, +40 inline }, нативный вход JSFunction @ +0x20, WasmFuncRef { +0x38/+0x48 цель вызова, +0x40 typeDef }). Все они заново вычисляются в рантайме самотестами цепочки; предполагается только расположение полей в структурах. PAC не актуален (XUL — arm64-бинарник, не arm64e); стаб с ленивым связыванием разрешает цель при первом вызове, так что смещения из dyld shared cache не нужны.

Область применения / честные ограничения

Этот PoC выполняется в процессе оболочки без песочницы. В реальной атаке на Firefox цепочка срабатывает внутри контентного процесса, где песочница macOS запрещает posix_spawnp — для полной компрометации требуется отдельная уязвимость для побега из OS-песочницы (см., например, анализ стадии 2 в CVE-2026-2796-and-CVE-2026-2768-escape-the-wasm-box).

Меры противодействия

  • Обновитесь до Firefox / Thunderbird ≥ 152.0.6 (ESR ≥ 140.13).
  • Многоуровневая защита: javascript.options.wasm=false блокирует вектор срабатывания.

Ссылки

  • MFSA-2026-67
  • NVD: CVE-2026-15718
  • Fix: https://github.com/mozilla-firefox/firefox/commit/4441102e62e8

Отказ от ответственности

Только для исследований в области безопасности, обучения и защитного тестирования. Уязвимость исправлена в текущих выпусках Firefox/Thunderbird. Не используйте против систем, которыми вы не владеете или на тестирование которых у вас нет явного разрешения.

Скачать инструмент