
Apache Traffic Server 10.2.0 - Élevé - Distant - SSRF - ESI unix recvport
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · ats-esi-unix-recvport
Classe : SSRF Portée : Distante
Apache Traffic Server 10.2.0 (b1df7334) - Apache Software Foundation
Le PluginVC FetchSM d'ESI rapporte le port de destination 0. Le remap traite le port 0 comme un UDS et réécrit le schéma de l'include en http+unix afin qu'il corresponde aux règles map_with_recv_port http+unix:// destinées uniquement aux listeners UDS. Un esi:include d'apparence publique de http://www.example.com/secret atteint alors l'origine unix-socket. Le GET /secret TCP reste sur la map TCP. Le CONTROL sans la map unix recv-port inline l'origine TCP (aucun témoin). Le schéma d'include http+unix lui-même est BAD_SCHEME dans le validateur de juillet 2026.
Un esi.so typique plus une seule map ne déclenche pas cela. Nécessite ESI plus au moins une ligne map_with_recv_port http+unix://. Valeurs par défaut remap_required: 1 et number_of_redirections: 0.
Ce n'est pas CVE-2026-58178 (littéraux privés, file://, commentaires imbriqués, plafond de profondeur fermé).
| ID | pas encore de CVE |
| Classe | SSRF |
| Portée | Distante (HTTP non authentifié vers un vhost ESI) |
| CWE | CWE-918 |
| CVSS | Élevé : 8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Produit | Apache Traffic Server |
| Affecté | 10.2.0 (b1df7334b39a878971c376da849e8da4984918b6) ESI plus map_with_recv_port http+unix |
| Auth | aucune. Plugin ESI. Map unix recv-port. |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:18750 / 18751 uniquement. Image ats-10.2.0-lab:local. |
J'ai épinglé le tag 10.2.0, commit b1df7334b39a878971c376da849e8da4984918b6. Image construite depuis les sources.
HTTP non authentifié vers un vhost ESI dont le remap contient map_with_recv_port http+unix://. Include src que l'attaquant peut influencer (origine compromise, ESI stocké, ou $(HTTP_HEADER{...})).
| Méthode | Cible | Privilège |
|---|---|---|
GET /page non authentifié avec ESI include http://www.example.com/secret | Le port de destination 0 de FetchSM correspond à map_with_recv_port http+unix://www.example.com/ (RemapProcessor.cc:87-114, PluginVC.h:274-278) | Reconnaissance / SSRF (prouvé en lab) : le corps client a inline ATS-ESI-UNIX-RECVPORT-WITNESS depuis l'origine UDS. |
| Idem | écriture au premier ordre / shell | Intégrité : aucune. Aucune écriture au premier ordre. Aucun shell. |
CONTROL GET /page sans map unix recv-port | include de l'origine TCP | Fermé (prouvé en lab) : inline TCP-ORIGIN-OK, aucun témoin. |
Client TCP GET /secret sur le vhost poc | map TCP | Fermé (prouvé en lab) : TCP-ORIGIN-OK, aucun témoin. |
Prouvé en lab vs déduit : control sans témoin, page poc avec témoin, /secret TCP poc sans témoin : lab. L'influence de src via ESI stocké ou expansion d'en-tête relève du modèle de confiance ESI documenté, non re-prouvé ici. L'include du lab est un http://www.example.com/secret statique sur /page.
Nécessite : le plugin ESI plus map_with_recv_port http+unix. Valeurs par défaut remap_required: 1. number_of_redirections: 0.
| Surface | Lab |
|---|---|
| CONTROL sans table de ports de réception unix | control-no-witness=yes, intègre TCP-ORIGIN-OK |
Client TCP GET /secret | poc-tcp-secret-no-witness=yes |
Schéma d'include http+unix | validateur BAD_SCHEME |
file://, littéraux privés, commentaires imbriqués, plafond de profondeur | CVE-2026-58178 fermé |
| Liste de refus d'hôtes sans DNS | documenté ; inopérant sur remap_required: 1 |
Échec de remap_required: 1 | 404 |
number_of_redirections: 0 | suivi de Location désactivé |
PluginVCCore met à zéro passive_addr_struct. PluginHttpConnectInternal ne définit que active_addr (le client d'origine). Le HttpSM de FetchSM s'exécute sur le PluginVC passif. attach_client_session copie netvc->get_local_addr() dans client_info.dst_addr. L'adresse locale passive est la structure mise à zéro. host_order_port() vaut 0.
Recherche de remap (RemapProcessor.cc:87-114) : le port 0 signifie UDS. Le schéma est réécrit http -> http+unix afin que map_with_recv_port http+unix:// corresponde. Le test unitaire test_RemapRules.cc:237-240 le documente.
Le validateur de juillet rejette le schéma d'include http+unix. Il ne rejette pas un include http:// dont le saut de remap interne est devenu unix parce que le port de destination valait 0.
Fausses pistes : traiter le esi.so typique + un map comme ce résidu (CONTROL prouve que ce n'est pas le cas) ; signaler la liste de refus d'hôtes sans DNS (documenté, inopérant sur remap_required=1) ; affirmer que file:// fonctionne encore ; s'attendre à ce que le TCP /secret suive la map unix.
Mise en scène : un reverse shell. L'oracle est un témoin intégré provenant de l'origine UDS, avec le TCP /secret toujours en TCP.
python3 ats-esi-unix-recvport-Abraxas-Labs.py
ou
cd lab
./run.sh
Boucle de preuve de concept 127.0.0.1:18750, contrôle 127.0.0.1:18751. Projet Compose ats-esi-unix-recvport. Image ats-10.2.0-lab:local. Témoin ATS-ESI-UNIX-RECVPORT-WITNESS. Dernière ligne :
SUCCESS ats-esi-unix-recvport control-no-witness=yes poc-page-witness=yes poc-tcp-secret-no-witness=yes ATS-ESI-UNIX-RECVPORT-WITNESS
Ne pas traiter le port de destination 0 du FetchSM PluginVC comme une correspondance de port de réception UDS. Conserver map_with_recv_port http+unix:// pour les véritables listeners UDS. Les inclusions ESI de http://host/ doivent rester sur la table TCP même lorsqu'une règle de port de réception http+unix existe pour cet hôte.