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

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

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

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

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

Категории

Все категории
Loading categories
Bootjack — Инструмент для эксплуатации переполнения при обработке ошибок ICMP в EDK II UEFI PXE (CVE-2026-97631): формирует поддельные ICMP-пакеты, внедряет подложный EFI_EVENT и выгружает память DXE через UART. | Kitploit
Инструменты/GitHubGitHub/rayanziani/bootjack
Безопасность встроенных системСниффинг и анализ пакетовАнализ уязвимостейЭксплуатацияШелл-кодСетевая безопасностьБезопасность оборудования и IoTРазработка Полезной НагрузкиАнализ ПрошивокЭксплуатация Бинарных Файлов
GitHub
15 дней назадЕщё не проверено

Популярное

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

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

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

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

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

Bootjack

Инструмент для эксплуатации переполнения при обработке ошибок ICMP в EDK II UEFI PXE (CVE-2026-97631): формирует поддельные ICMP-пакеты, внедряет подложный EFI_EVENT и выгружает память DXE через UART.

Репозиторий

CVE-2026-97631: средство чтения памяти DXE до загрузки

Инструментарий для переполнения при обработке ошибок ICMP в драйвере EDK II PXE Base Code (NetworkPkg/UefiPxeBcDxe, GHSA-99cj-7hg9-mp4m, CVSS 4.0 9.5).

Во время PXE-загрузки драйвер копирует сообщение об ошибке ICMP в буфер фиксированного размера 504 байта. Более длинное сообщение превращается в линейную запись за пределы этого буфера, в пул DXE. Поскольку адрес назначения записи совпадает с адресом самого буфера, полезная нагрузка не зависит от позиции: байт i датаграммы попадает по адресу &Mode->IcmpError + i. Переполнение внедряет поддельный EFI_EVENT; ядро DXE диспетчеризует его через обычный путь CoreSignalEvent; полезная нагрузка восстанавливает событие из снимка, обходит выбранные оператором диапазоны памяти и возвращает EFI_SUCCESS, чтобы загрузка продолжилась.

Радиус поражения остаётся внутри собственной памяти DXE прошивки. Ни записи во flash, ни механизма персистентности, ни артефактов ОС.

Структура

include/pxe_layout.h   EFI_PXE_BASE_CODE_ICMP_ERROR, IEVENT offsets, wire structs
include/craft.h        one packet = one primitive
include/graft.h        counterfeit event + payload parameter block
include/layout.h       the overflow region (single source of truth)
src/payload.S          ring-0 payload: restore, walk ranges, stream out
src/craft.c            packet construction, IPv4 + IPv6
src/graft.c            IEVENT overlay, parameter block
src/layout.c           overflow assembly, shared by sender and simulator
src/main.c             pxeinj: sniff xid, probe, send
src/net.c              raw L3 transport, DHCP xid sniffer
src/recv.c             pxerecv: serial collector, dump + map
sim/sim.c              host harness that proves the chain
tools/fw_offsets.py    pool offsets from a debug firmware build

Сборка

Полезная нагрузка:

as --64 -o build/payload.o src/payload.S
ld -Ttext=0 -e payload_start --oformat elf64-x86-64 -o build/payload.elf build/payload.o
objcopy -O binary --only-section=.text build/payload.elf build/payload.bin

Результат — 378 байт, позиционно-независимый, без релокаций.

Отправитель и получатель используют POSIX (AF_PACKET, IP_HDRINCL, termios) и собираются с помощью make в Linux. Симулятор собирается с MSVC через Makefile.win:

cl /nologo /W3 /O2 /Iinclude /Fe:build\sim.exe sim\sim.c src\craft.c src\graft.c src\layout.c

Цепочка, как доказано симулятором

build/sim.exe отображает поддельную страницу пула, записывает переполнение туда, где это сделал бы уязвимый memcpy, проверяет, что полученный IEVENT отправит полезную нагрузку, вызывает полезную нагрузку как реальный машинный код, а затем проверяет:

  • событие восстановлено байт в байт
  • дампленные байты равны исходному диапазону
  • кадры открытия/закрытия целы, поэтому усечённый дамп можно отличить
  • мёртвый UART не приводит к зависанию вызова
  • контрольные суммы датаграмм ICMP проверяются, и переполнение попадает по смещению, с которого копирует драйвер
  • встроенный BOOTP xid сохраняется дословно

26 проверок по компоновке, ABI, кадрированию и построению пакетов. Это доказывает, что части согласуются друг с другом. Это не доказывает адрес пула конкретной прошивки, который является выделением во время выполнения.

Работа

Два режима, используемые по порядку.

Probe: только легальный путь, без записи за границы.

pxeinj --target 10.0.0.50 --spoof 10.0.0.1 --sniff --probe --send

Корректно сформированная ICMP-ошибка размером 504 байта. Тот же спуфинг, та же встроенная BOOTP-транзакция, всё то же самое. Если клиент продолжает загрузку, значит ошибка была принята и достигнут уязвимый цикл копирования. Неразрушающее подтверждение, и ему не нужен адрес пула.

Overflow: отказывается собираться, пока не существуют три вещи: база пула (tools/fw_offsets.py), исходные байты события (--shadow) и хотя бы один диапазон.

pxeinj --target 10.0.0.50 --spoof 10.0.0.1 --xid 0xdeadbeef \
       --pool-base 0x7f12345000 --payload build/payload.bin \
       --ranges ranges.txt --shadow shadow.bin --uart 0x3f8 --send

pxerecv -d /dev/ttyUSB0 -o dump.bin -m dump.map

ranges.txt — по одному START-END на строку, в hex без 0x; см. ranges.example.txt для оценки размера и времени. Путь переполнения для v6 отключён: probe работает через v6, запись — нет, пока граница копирования для v6 не будет заново выведена из пропатченного исходного кода.

Почему это тихо

  • никаких выделений Boot Services, логирования или блокировок внутри payload
  • никаких правок IDT/GDT/CR/MSR, никаких перехватов прерываний, никаких отладочных регистров
  • объект восстанавливается до начала дампа, а не после
  • вывод идёт через опрос UART, поэтому ничего не попадает в буфер, управляемый прошивкой
  • возвращает EFI_SUCCESS на нормальном пути notify, поэтому загрузка продолжается
  • SignalLink события самосогласован, поэтому обход списка не вызывает assert

Остаточные следы присущи самому багу: событие было просигнализировано в момент, когда это обычно не происходит, страница пула остаётся «грязной», а если платформа измеряет DXE через TPM, значение PCR будет таким, каким оно было на момент начала загрузки. Всё сверх этого не является свойством данного бага.

Защитные ограничения в коде

  • --send обязателен; по умолчанию выполняется пробный запуск
  • переполнение отказывается собираться без --pool-base, --payload, --shadow и непустого списка диапазонов. Каждый из них имеет свой специфический способ повредить прошивку при угадывании, поэтому ни один не является опциональным
  • --shadow должен содержать сигнатуру EFI_EVENT по ожидаемому смещению, что ловит и файл, заполненный нулями, и неверный --event-off одной проверкой, а не в момент диспетчеризации
  • probe — отдельный режим и не может писать за границы
  • опрос UART ограничен, поэтому отсутствующий 16550 не может подвесить загрузку; как только оценка исчерпана, UART отключается, и приёмник в RAM, если он есть, продолжает работу
  • закрывающий фрейм делает усечение видимым, а не молчаливым

Ограничения

  • Адрес пула для Mode->IcmpError — это выделение времени выполнения, и он различается для разных сборок прошивки. Его нельзя вывести из карты компоновки. tools/fw_offsets.py даёт смещения; базу нужно измерить на целевой прошивке, например из трассировки DEBUG_POOL, и затем закэшировать.
  • sizeof(EFI_PXE_BASE_CODE_MODE) и offsetof(..., IcmpError) меняются между релизами edk2. Значения по умолчанию в tools/fw_offsets.py — отправные точки, а не значения, которым можно доверять.
  • Точное выражение, из которого вычисляется ошибочная граница копирования, не указано в advisory, и исправление (#13302) его меняет. Прочитайте две функции DpcHandle в целевом дереве, прежде чем полагаться на смещение переполнения.
  • Восстановление события требует снимка, сделанного до переполнения. Без него восстановление записывает нули и оставляет повреждённое событие в списке сигналов ядра, в который при следующем вызове CoreSignalEvent будет выполнен обход. По этой причине инструмент отказывается собираться без --shadow.
Скачать инструмент