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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-56848 — PoC-эксплойт для CVE-2026-56848 — ошибка heap-use-after-free в HTTP/2-реализации Node.js, позволяющая удалённую неаутентифицированную DoS-атаку. Включает raw-socket триггер, инструкции по сборке с ASan и Docker-цель. | Kitploit
Инструменты/GitHubGitHub/open-flaw/cve-2026-56848
Анализ уязвимостейДинамический анализ кода (DAST)ЭксплуатацияВеб-безопасностьСетевая безопасность
GitHubopen-flaw/cve-2026-56848

CVE-2026-56848

PoC-эксплойт для CVE-2026-56848 — ошибка heap-use-after-free в HTTP/2-реализации Node.js, позволяющая удалённую неаутентифицированную DoS-атаку. Включает raw-socket триггер, инструкции по сборке с ASan и Docker-цель.

Репозиторий
411 месяц назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2026-56848

Описание NVD

Ошибка в обработке HTTP/2 в Node.js допускает реентерабельный вызов nghttp2_session_mem_send() во время выполнения nghttp2_session_mem_recv(), что приводит к использованию после освобождения в куче (heap-use-after-free).

Эта уязвимость затрагивает Node.js 26.x, 24.x и 22.x.

(Примечание: указанные в описании версии относятся только к пакету nodejs из вышестоящего репозитория и не относятся к пакету nodejs, распространяемому через Alpine.

Линия релизаУязвимыеИсправленные
22.x (LTS)≤ 22.23.122.23.2
24.x (LTS)≤ 24.18.024.18.1
26.x≤ 26.5.026.5.1
  • Степень серьезности: Высокая (CVSS 7.5, AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — удалённая, неаутентифицированная DoS-атака через повреждение кучи)
  • Сообщил: hahahkim (HackerOne #3833629)
  • Исправил: Matteo Collina (mcollina)
  • Исправляющий коммит (v22): daa6d25e3dce — "http2: defer rst stream while in scope" (nodejs-private/node-private#921)
  • Раскрыто: в выпусках безопасности Node.js, 2026-07-29

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

Http2Stream::SubmitRstStream() в src/node_http2.cc принудительно очищает ожидающие исходящие данные перед постановкой RST_STREAM в очередь:```cpp void Http2Stream::SubmitRstStream(const uint32_t code) { CHECK(!this->is_destroyed()); code_ = code;

// (NGHTTP2_CANCEL is deferred — fix for an older double-free) if (session_->is_in_scope() && is_stream_cancel(code)) { session_->AddPendingRstStream(id_); return; }

// If possible, force a purge of any currently pending data here to make // sure it is sent before closing the stream. ... if (session_->SendPendingData() != 0) { // ← RE-ENTRANT mem_send() session_->AddPendingRstStream(id_); return; }

FlushRstStream(); }

`SendPendingData()` вызывает `nghttp2_session_mem_send()` ([node_http2.cc:1970](https://github.com/nodejs/node/blob/v22.23.1/src/node_http2.cc#L1970)). Его единственная защита от повторного входа — `is_sending()`, которая защищает от *отправки во время отправки* (когда запись уже выполняется) — **но не от отправки во время получения**. Когда `SubmitRstStream()` выполняется из цепочки обратных вызовов `nghttp2_session_mem_recv()` («в области видимости»), сброс запускает `mem_send()` реентерабельно.

Реентерабельный `mem_send()` сбрасывает кадры, обработка которых на стороне отправки уничтожает потоки (`nghttp2_session_close_stream_on_goaway()` → `on_stream_close` → `Http2Stream::Destroy()` → освобождение C++-объекта `Http2Stream`). На освобождённый поток всё ещё ссылается выполняющаяся операция приёма: сам `SubmitRstStream()` продолжает выполняться на освобождённом `this` (его завершающий `FlushRstStream()` читает `is_destroyed()`), а внешний `mem_recv()` продолжает обходить состояние кадров/заголовков закрытого потока → **использование после освобождения**.

### Цепочка триггера (всё внутри одного вызова `nghttp2_session_mem_recv()`)

1. Атакующий отправляет `GOAWAY(lastStreamID=0, NO_ERROR)`, сразу за которым следуют кадры `HEADERS` для новых потоков (3, 5, 7, …) в одном TCP-сегменте.
2. `mem_recv()` сервера обрабатывает GOAWAY → JS `session.close()` → `session.closed = true`, и исходящий GOAWAY **подан на отправку, но ещё не отправлен**.
3. nghttp2 отклоняет новые входящие потоки только после того, как GOAWAY действительно *отправлен* (`session_allow_incoming_new_stream()` проверяет `TERM_ON_SEND | SENT`, а не `SUBMITTED`), поэтому `HEADERS(3)` всё ещё принимается.
4. JS-функция `onSessionHeaders()` видит новый поток на закрытой сессии и отклоняет его: `handle.rstStream(NGHTTP2_REFUSED_STREAM)` (lib/internal/http2/core.js).
5. C++ `SubmitRstStream(NGHTTP2_REFUSED_STREAM)` выполняется в области видимости (внутри `mem_recv`), `REFUSED_STREAM ≠ CANCEL` → переход к `SendPendingData()` → **реентерабельный `nghttp2_session_mem_send()`**.
6. Реентерабельная отправка сбрасывает исходящий GOAWAY; обработка GOAWAY на стороне отправки в nghttp2 закрывает входящие потоки с id > 1 (`session_close_stream_on_goaway(..., NGHTTP2_REFUSED_STREAM)`), вызывая `on_stream_close` → `Http2Stream::Destroy()` освобождает C++-объект потока 3.
7. Выполнение возвращается в `SubmitRstStream()` на освобождённом объекте (`FlushRstStream()`), а внешний `mem_recv()` продолжает работу с повреждённым состоянием сессии/потока → UAF.

Доказательство из `NODE_DEBUG_NATIVE=http2` на уязвимом сервере (одно 86-байтовое чтение):```
receiving 86 bytes, offset 0
complete frame received: type: 7          ← GOAWAY
submitting goaway                          ← GOAWAY submitted, NOT yet sent
beginning headers for stream 3             ← still accepted (only SUBMITTED)
handle headers frame for stream 3          ← JS: session.closed → refuse
sending rst_stream with code 7             ← SubmitRstStream(REFUSED_STREAM), in scope
sending pending data                       ← RE-ENTRANT mem_send()
stream 3 closed with code: 7               ← GOAWAY send closes stream 3
Removing stream: 3 / destroying stream     ← Http2Stream freed mid-recv

Поведенческая сигнатура

Вывод на уровне протокола идентичен для уязвимых и пропатченных сборок (обе в итоге отправляют только исходящий GOAWAY — в уязвимых сборках RST отправляется на уже закрытый поток, в пропатченных nghttp2 отбрасывает поставленные в очередь RST после того, как GOAWAY уходит первым). Разница внутренняя и видна с помощью NODE_DEBUG_NATIVE=http2:

  • Уязвимая: sending pending data появляется между sending rst_stream with code 7 и stream 3 closed with code: 7 — реентерабельный mem_send() выполняется в середине приёма данных и закрывает/уничтожает поток 3, пока mem_recv() ещё работает (крах под ASan).
  • Пропатченная: sending pending data между ними отсутствует — RST лишь ставится в очередь; поток 3 закрывается только во время обычного завершающего сброса после приёма.

PoC```

server.js # minimal http2.createServer() target (no handler needed) exploit.js # raw-socket HTTP/2 client that drives the trigger

### Быстрый запуск```bash
# Terminal 1: the target (any vulnerable node: 22.23.1 / 24.18.0 / 26.5.0 or older in their lines)
node server.js 8000                       # NODE_BIN=/path/to/node for a specific binary

# Terminal 2: the attack — a crash shows up in terminal 1 (ASan report / segfault)
node exploit.js --port 8000 --iterations 200

./bin/node (используемая ниже локальная ASan-сборка) не отслеживается в git — соберите его по инструкциям в разделе «Сборка уязвимого Node.js с инструментированием ASan» или используйте Docker-подход.

Эксплойт выводит статус по каждому соединению; SKIPPED (no handshake) после первого соединения означает, что цель уже погибла от атаки.

Docker

Dockerfile собирает уязвимую цель v22.23.1 с ASan внутри контейнера (локальный инструментарий не нужен — только демон Docker):```bash docker build -t cve-2026-56848 . docker run --rm -p 8000:8000 --name cve-target cve-2026-56848

from the host, in another terminal:

you could reuse ./bin/node

node exploit.js --port 8000 --iterations 10

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