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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-84118-who-labeled-the-crit-as-a-high — Доказательство концепции для CVE-2026-84118 — use-after-free в сборщике мусора SpiderMonkey, приводящий к чтению/записи за пределами границ и потенциальному выполнению кода. Включает детерминированный триггер SEGV и исследование по эскалации до произвольного чтения и обхода ASLR. | Kitploit
Инструменты/GitHubGitHub/sneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high
Криминалистика памятиАнализ уязвимостейЭксплуатацияВеб-безопасностьЭксплуатация Бинарных Файлов
GitHubsneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high

CVE-2026-84118-who-labeled-the-crit-as-a-high

Доказательство концепции для CVE-2026-84118 — use-after-free в сборщике мусора SpiderMonkey, приводящий к чтению/записи за пределами границ и потенциальному выполнению кода. Включает детерминированный триггер SEGV и исследование по эскалации до произвольного чтения и обхода ASLR.

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
Репозиторий
111 часов назадЕщё не проверено

CVE-2026-84118 — Использование после освобождения в сборщике мусора SpiderMonkey (Bug 2057457)

Это один из тех случаев, когда Mozilla пометила Critical как High. Так что, возможно, кому-то стоит пойти и попросить Firefox обновить выплату оригинальным охотникам за багами, если это так.

КРАТКО: Вы можете получить примитив OOB R на управляемом указателе, а затем начать двигаться вверх и вниз от этого указателя. Так что если вы наведёте управляемый указатель на массив, то поздравляю — вы можете делать забавные вещи.

PoC содержит только часть с SEGV, так что остальное — это увлекательное приключение по наведению на массив и переходу в WASM по вашему выбору.

Детерминированный proof-of-concept с SEGV для релизной сборки Firefox/SpiderMonkey 154.0.1. Исправлено в 155 (переработка AtomMarking). Серьёзность по версии Mozilla: HIGH.

Запуск PoC

root@kitploit:~
/path/to/release/js poc.js

Воспроизведено на 154.0.1: 3/3 на обычной оптимизированной оболочке (SIGSEGV, выход 139), 5/5 на оболочке release+gczeal, идентичный сбой при каждом запуске:

root@kitploit:~
SEGV по адресу 0x000000000014 (READ)
JS::shadow::Zone::gcState()  <- zone == nullptr, смещение +0x14

Корневая причина

В 154 смешиваются попери-zone битовые карты пометки атомов с отслеживанием ссылок. Symbol, удерживаемый только слабо — здесь, захваченный как слабое поле Value внутри IC-стаба Baseline CacheIR — и на который ссылаются из не собираемой зоны, никогда не помечается повторно, когда зона атомов собирается в GC с областью действия зоны. Результат — устаревшее ребро к выметенной/перемещённой ячейке.

Убийственный выстрел в релизной сборке — вторая, статическая ошибка: MightBeForwarded<JS::Symbol> жёстко задано как false, поэтому IsForwarded возвращает false без проверки (gc/Marking-inl.h:92-97), и каждый путь исправления указателей, управляемый этим условием, молча пропускает ребро. Когда зона атомов уплотняется, сильные рёбра обновляются корректно, но это слабое ребро CacheIR остаётся навсегда висящим по старому адресу Symbol-жертвы. (Отладочные сборки ловят это как Assertion failure: !t->isForwarded(), gc/Marking-inl.h:94.)

Как PoC превращает висящее ребро в SEGV

PoC не просто оставляет устаревший указатель на переиспользуемую кучу — он добивается munmap резервной страницы, так что уже следующее разыменование вызывает сбой.

  1. Изоляция чанков по зонам. Пулы чанков GC являются попери-zone (Zone::availableChunks/fullChunks), поэтому чанки зоны атомов содержат только арены зоны атомов. Судьбой чанка можно управлять исключительно за счёт времени жизни атомов/symbol'ов.
  2. Подготовка кучи. 300 Symbol'ов-"магнитов" (удерживаемых в живых) занимают ранний чанк и служат назначением уплотнения. Затем 150 000 одноразовых Symbol'ов заполняют ~4 свежих чанка по 1 МБ, так что Symbol-жертва оказывается в середине распыления в чанке, содержащем только обречённые распылённые symbol'ы.
  3. Танец со слабо удерживаемым symbol'ом (строки 21-31, хрупкий к байткоду — должен оставаться дословно): c.eval(b) заставляет IC верхнеуровневого вызова захватить Symbol в слабом поле стаба; b = undefined убирает последний сильный корень; распыление сбрасывается; два GC с областью действия зоны (gc("zone"), schedulezone(c) + schedulezone("") + gc("zone") — пустая строка планирует зону атомов) выметают мёртвое распыление, уплотняют жертву в арену магнитов, пропускают исправление слабого ребра и освобождают арену жертвы. Её чанк теперь полностью пуст.
  4. munmap. gcparam("minEmptyChunkCount", 0) делает каждый пустой чанк подлежащим истечению; во время sleep(0.5) задача BackgroundDecommitTask выполняет -> -> — настоящий munmap чанка жертвы. (Высвобождение на уровне арены — это лишь — читаемые нули — освобождение целого чанка — это единственный путь munmap, поэтому изоляция чанков на шаге 1 имеет значение.)

За пределами сбоя на нулевой странице

Это не просто DoS. Продемонстрированные эскалации (PoC и журналы в исследовательских каталогах GC-NDAY/ и CHAIN/):

  • Адрес сбоя, выбираемый атакующим (segv9): после munmap переключение полупространств при minorgc() заставляет nursery захватить освобождённый VA; сырое распыление плотных double записывает qword атакующего поверх поля zone устаревшего заголовка арены. Затем выметание разыменовывает attacker_ptr + 0x14 — детерминированно 3/3 по адресу 0x424242424256.
  • Управление вердиктом + повторяемые чтения: загруженное значение выбирает вердикт живости слабого ребра; вердикт "LIVE" сохраняет висящее ребро и разыменовывает его снова при каждом последующем основном GC (чтения, выбираемые атакующим, + оракул из 1 бита, наблюдаемый скриптом). Вердикт "DEAD" самовосстанавливается.
  • Цепочка из двух ошибок: настоящий js::Zone*, утёкший через отдельный спекулятивный побочный канал, был внедрён через этот refill; сборщик потребил поддельные метаданные арены без сбоя (управляющая посадка с возмущением в 1 бит вызывает сбой), демонстрируя композицию обхода ASLR -> внедрения UAF.
  • Ограниченный негатив: прямой fakeobj через это семейство стабов архитектурно заблокирован — уплотнение корректно исправляет сильные рёбра, висят только слабые рёбра, а их потребители при выметании работают только с ветвлениями.
Скачать инструмент
expireEmptyChunkPool
FreeChunkPool
UnmapPages
madvise(MADV_DONTNEED)
  • Сбойное разыменование. Финальный gc() выметает данные JIT: sweepJitDataOnMainThread -> ICEntry::traceWeak -> TraceWeakCacheIRStub читает устаревший указатель Symbol, затем SweepingTracer::onEdge (gc/Marking.cpp:3195) выполняет арифметику чанков по устаревшему адресу, чтобы загрузить поле zone заголовка арены. Страница исчезла/обнулена, поэтому zone == nullptr, и zone->isGCSweeping() читает nullptr + 0x14 (shadow::Zone::gcState) -> SIGSEGV. В момент сбоя rcx содержит устаревший указатель Symbol, а rdx — базовый адрес munmapped-чанка.