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

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

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

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

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

Категории

Все категории
Loading categories
verify-ghsa-c4j6-fc7j-m34r — OOB-верификатор для GHSA-c4j6-fc7j-m34r / CVE-2026-44578 (SSRF через WebSocket-upgrade в Next.js) | Kitploit
Инструменты/GitHubGitHub/panchocosil/verify-ghsa-c4j6-fc7j-m34r
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьТестирование на ПроникновениеRed Teaming
GitHubpanchocosil/verify-ghsa-c4j6-fc7j-m34r

verify-ghsa-c4j6-fc7j-m34r

OOB-верификатор для GHSA-c4j6-fc7j-m34r / CVE-2026-44578 (SSRF через WebSocket-upgrade в Next.js)

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

Популярное

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

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

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

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

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

verify-ghsa-c4j6-fc7j-m34r

In-band верификатор для GHSA-c4j6-fc7j-m34r / CVE-2026-44578 — Server-Side Request Forgery (SSRF) в Next.js через WebSocket upgrade-запросы.

⚠️ Только для авторизованного тестирования безопасности. Вы несёте ответственность за то, чтобы у вас было разрешение на тестирование каждой цели, которую вы передаёте этому скрипту.

Уязвимость

ПолеЗначение
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CWECWE-918 (SSRF)
CVSS v3.18.6 (высокий) — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Затронутые версииnext >=13.4.13 <15.5.16, >=16.0.0 <16.2.5
Исправленные версии15.5.16, 16.2.5
Коммит с исправлениемc4f69086
Не затронутыРазмещённые на Vercel; output: "export"; развёртывания за обратным прокси, который не передаёт Upgrade

Как именно работает баг (проверено эмпирически на 15.5.15 против 15.5.16)

  1. Атакующий открывает TCP-соединение к самостоятельно размещённому процессу Next.js и отправляет HTTP/1.1 WebSocket upgrade, чей request-URI является абсолютным URL:

    GET http://anything/<path> HTTP/1.1
    Host: <target>
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Version: 13
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    
  2. В resolveRoutes URL содержит // (как и любой абсолютный URI), что соответствует ветке «нормализация повторяющихся слэшей». Эта ветка возвращается раньше времени с { finished: true, statusCode: 308, parsedUrl: <mangled> }. Нормализатор схлопывает http://host/path в http:/host/path (один слэш).

  3. В router-server.ts обработчик upgrade до исправления игнорировал finished/statusCode и проверял только parsedUrl.protocol. Поскольку протокол переживает нормализацию, вызывался proxyRequest(...).

  4. proxyRequest выполняет url.format(parsedUrl) над искажённым URL, получая http:/host:port/path. http-proxy разбирает этот target, не находит host (url.parse('http:/...').host === null) и откатывается к своему назначению по умолчанию: localhost:80 (или localhost:443 для https).

  5. Таким образом, на практике SSRF позволяет заставить Next открыть WebSocket upgrade на собственные localhost:80 / localhost:443 хоста Next.js с путём, контролируемым атакующим.

Исправление (коммит c4f69086) заставило обработчик upgrade проверять finished && !statusCode перед проксированием. Случай с 308-нормализацией теперь не проходит проверку !statusCode, и сокет вместо этого закрывается.

Почему callback-based OOB-верификатор не сработает для этого CVE

Прокси никогда не достигает внешнего хоста. Если вы настроите interactsh / Burp Collaborator / webhook canary и ожидаете, что процесс Next «позвонит домой», этого не произойдёт — соединение уходит на localhost целевой машины. Поэтому данный верификатор использует in-band сигнал, читаемый из upgrade-сокета: уязвимый сервер возвращает распознаваемое тело ошибки, исправленный сервер не возвращает ничего.

Практическое влияние

Цель SSRF ограничена, но всё ещё значима в реальных развёртываниях:

  • Sidecar-контейнеры / обратные прокси / админ-панели, размещённые на том же хосте, которые слушают 127.0.0.1:80 или :443 и доверяют запросам с localhost.
  • Docker-сокет, доступный по HTTP на 127.0.0.1:80 (редко, но встречается).
  • Path traversal в любой локальный HTTP-сервис с контролируемым атакующим URI-путём и семантикой WebSocket upgrade.

Метаданные-эндпоинты AWS / GCP / Azure (169.254.169.254) не доступны напрямую, поскольку баг привязывает назначение к localhost.

Модель детектирования

Для каждой цели скрипт открывает сырой TCP (или TLS) сокет, отправляет сформированный upgrade, читает ответ и формирует два сигнала:

  • verdict — присутствует ли баг.
  • impact_confirmed — действительно ли SSRF извлёк данные (т.е. совмещённый сервис на localhost:80/443 цели ответил, и мы получили его ответ).
ОтветВердиктimpact_confirmed
Содержит Internal Server Errorvulnerablefalse — баг доказан, но прокси ничего не нашёл на localhost
Начинается с HTTP/1.vulnerable_proxy_succeededtrue — реальные данные ответа извлечены
Пустой ответ / чистое закрытиеlikely_patchedfalse — также покрывает «не Next», «обратный прокси срезал Upgrade», «Vercel»
Идентичен контрольному запросу без Upgradefront_end_interceptsfalse — фронт-енд прокси перехватил оба зонда; SSRF так и не достиг Next
Всё остальноеinconclusivefalse

Когда impact_confirmed равен true, JSON-вывод также включает upstream_status, upstream_server и upstream_content_type, извлечённые из утёкшего ответа (полезно для разбора инцидента / написания отчёта).

Защита от ложных срабатываний фронт-енд прокси

По умолчанию каждая цель также получает контрольный зонд с той же строкой запроса с абсолютным URI, но без заголовков Upgrade (Connection: close). Если фронт-енд возвращает одинаковый ответ на оба зонда (строка статуса + размер в пределах допуска), значит, собственный фронт-енд хоста отклоняет саму строку запроса с абсолютным URI — nginx 400, Apache 400, CDN edge — и SSRF так и не достиг Next. Вердикт понижается до front_end_intercepts, а JSON-вывод включает front_end_status и front_end_server, извлечённые из ответа прокси, чтобы оператор мог определить, что перехватывает запросы.

Это устраняет реальное ложное срабатывание, наблюдаемое, когда самостоятельно размещённый Next находится за nginx/Apache: эти прокси отклоняют строку запроса зонда GET http:///x HTTP/1.1 стандартной ошибкой 400, которую детектор раньше ошибочно принимал за vulnerable_proxy_succeeded. Передайте --no-control-probe, чтобы отказаться от проверки и увидеть сырые вердикты.

Требования

  • Python 3.10+
  • Нет сторонних зависимостей (только стандартная библиотека)

Использование

# single target
python3 verify_ghsa_c4j6.py --target https://app.example.com

# multiple targets via flag repetition
python3 verify_ghsa_c4j6.py \
    --target https://app1.example.com \
    --target app2.example.com:3000 \
    --target 10.0.0.5:80

# from a file (one target per line; '#' for comments)
python3 verify_ghsa_c4j6.py --targets-file targets.txt

# from stdin
cat targets.txt | python3 verify_ghsa_c4j6.py

# JSON Lines output for downstream tooling
python3 verify_ghsa_c4j6.py --targets-file targets.txt --json

# Enumerate co-located services on the target's localhost:80/443 via the bug
python3 verify_ghsa_c4j6.py --target https://app.example.com --scan

# Same, with a custom path list
python3 verify_ghsa_c4j6.py --target ... --scan-paths-file my_paths.txt

Режим сканирования

--scan опрашивает встроенный список распространённых путей (модули статуса Apache/nginx, health- и metrics-эндпоинты, Spring Boot Actuator, Go pprof, эндпоинты Docker daemon, распространённые админ-панели, утёкшие конфигурационные файлы, маршруты Elasticsearch и т.д.) через SSRF-гаджет.

По умолчанию режим сканирования выполняет один дополнительный дифференциальный базовый зонд со случайным несуществующим путём для каждой цели. Последующие зонды помечаются DIFF только когда их сигнатура (status, длина тела) отклоняется от базовой — одинаковые 404 от апстрима, который «ничего не нашёл», помечаются как noise и не увеличивают счётчик попаданий. Передайте --no-differential, чтобы сообщать о каждом зонде, достигшем сервиса (прежнее поведение).

Вывод группируется по целям:

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