Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-28496-Lab — CVE-2026-28496을 재현하고 검증하기 위한 Docker 기반 실습 환경입니다. FOSSBilling의 Twig 렌더링에서 발생하는 서버 측 템플릿 주입(Server-Side Template Injection) 취약점을 다루며, 취약한 버전과 패치된 버전을 비교할 수 있습니다. | Kitploit
도구/GitHubGitHub/rootdirective-sec/cve-2026-28496-lab
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubrootdirective-sec/cve-2026-28496-lab

CVE-2026-28496-Lab

CVE-2026-28496을 재현하고 검증하기 위한 Docker 기반 실습 환경입니다. FOSSBilling의 Twig 렌더링에서 발생하는 서버 측 템플릿 주입(Server-Side Template Injection) 취약점을 다루며, 취약한 버전과 패치된 버전을 비교할 수 있습니다.

저장소 보기
123개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-28496 - FOSSBilling 서버사이드 템플릿 인젝션 - Twig 렌더링

요약

이 저장소에는 CVE-2026-28496을 재현 및 검증하기 위한 로컬 Docker 랩이 포함되어 있습니다. CVE-2026-28496은 FOSSBilling의 Twig 템플릿 렌더링 동작에 영향을 미치는 서버사이드 템플릿 인젝션 취약점입니다.

FOSSBilling은 무료 오픈소스 결제 및 고객 관리 플랫폼입니다. 0.8.0 이전 버전은 안전하지 않은 Twig 템플릿 렌더링 동작으로 인해 제공된 템플릿 표현식을 평가할 수 있습니다. 이 랩에서는 패치된 비교 대상으로 FOSSBilling 0.8.0을 사용합니다.

이 랩에서는 두 FOSSBilling 버전을 비교합니다.

서비스FOSSBilling 버전목적URL
vuln0.7.2취약한 비교 대상http://localhost:8081
patched0.8.0패치된 비교 대상http://localhost:8082

이 로컬 랩에서 시연되는 HTTP 검증 경로는 다음과 같습니다.```text Unauthenticated HTTP request in this local FOSSBilling 0.7.2 lab → POST /api/system/system/string_render → JSON body contains _tpl={{ 7*7 }} → vulnerable target renders the Twig expression → patched target does not expose the same tested API behavior

취약한 대상에서 API 호출은 반환합니다:```json
{"result":"49","error":null}

패치된 대상에서 동일한 요청이 반환됩니다:```json {"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}

이 실험실은 FOSSBilling 0.7.2 및 FOSSBilling 0.8.0을 사용하여 취약한 HTTP 동작과 패치된 HTTP 동작을 검증합니다.

이 실험실은 의도적으로 로컬 Docker 서비스로 범위가 제한됩니다. 외부 시스템을 대상으로 하지 않으며, 웹 셸, 악성 코드, 지속성, 외부 콜백, 데이터베이스 덤프 또는 파괴적 페이로드를 포함하지 않습니다.

## Verified Facts

| 주장                                                                               | 증거                                                                                                           | 이 실험실에서 확인하는 방법                                                              |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| CVE-2026-28496은 FOSSBilling 0.8.0 이전 버전에 영향을 미칩니다.                         | 공개 CVE 및 권고 메타데이터는 FOSSBilling 0.8.0 이전 버전이 Twig SSTI의 영향을 받는 것으로 식별합니다.                     | 참조 섹션을 검토하고 취약한 대상 버전과 패치된 대상 버전을 비교하십시오.  |
| FOSSBilling 0.7.2가 취약한 비교 대상으로 사용됩니다.                      | 취약한 서비스는 공식 `fossbilling/fossbilling:0.7.2` Docker 이미지에서 빌드됩니다.                    | `vuln/Dockerfile`을 검사하고 `docker compose ps -a`를 실행하십시오.                              |
| FOSSBilling 0.8.0이 패치된 비교 대상으로 사용됩니다.                         | 패치된 서비스는 공식 `fossbilling/fossbilling:0.8.0` Docker 이미지에서 빌드됩니다.                       | `patched/Dockerfile`을 검사하고 `docker compose ps -a`를 실행하십시오.                           |
| 취약한 HTTP 경로는 `/api/system/system/string_render`입니다.                     | 취약한 대상은 `_tpl={{ 7*7 }}`에 대해 `result: \"49\"`가 포함된 JSON을 반환합니다.                                       | `python3 poc/poc.py --url http://localhost:8081`을 실행하십시오.                                  |
| 패치된 대상은 동일한 HTTP 동작을 노출하지 않습니다.                          | 패치된 대상은 `Unknown API call system/system/string_render`를 반환합니다.                                         | `python3 poc/poc.py --url http://localhost:8082`를 실행하십시오.                                  |
| PoC는 HTTP 전용입니다.                                                               | `poc/poc.py`는 HTTP POST 요청을 보내며 Docker, Docker Compose, 셸 명령 또는 컨테이너 API를 호출하지 않습니다. | `poc/poc.py`를 검사하십시오.                                                                  |
| 실험실은 Docker Compose 시작 중에 두 FOSSBilling 대상을 자동 설치합니다.       | 일회성 설치 관리자 사이드카 컨테이너가 설정을 완료하고 상태 0으로 종료합니다.                                   | `docker compose ps -a` 및 `docker compose logs installer-vuln installer-patched`를 실행하십시오. |
| 취약한 대상은 무해한 Twig 표현식을 렌더링합니다.                         | 포트 8081의 HTTP 응답은 `{\"result\":\"49\",\"error\":null}`입니다.                                                | 취약한 PoC 명령을 실행하십시오.                                                        |
| 패치된 대상은 테스트된 API 경로를 통해 동일한 표현식을 렌더링하지 않습니다. | 포트 8082의 HTTP 응답은 코드 `879`가 포함된 JSON API 오류입니다.                                              | 패치된 PoC 명령을 실행하십시오.                                                           |

## Assumptions and Unknowns

이 실험실은 공개 취약점 연구에서 FOSSBilling 0.8.0 이전 버전이 영향을 받는 것으로 식별하고, 0.7.2가 테스트된 체인에서 사용된 최신 취약한 릴리스이므로 취약한 비교 대상으로 FOSSBilling 0.7.2를 사용합니다.

이 실험실은 공개 권고 메타데이터가 0.8.0을 패치된 버전으로 식별하므로 패치된 비교 대상으로 FOSSBilling 0.8.0을 사용합니다.

이 실험실은 관찰 가능한 HTTP 동작에 초점을 맞춥니다:```text
POST /api/system/system/string_render

이 JSON 본문과 함께:```json {"_tpl":"{{ 7*7 }}"}

이 실습은 FOSSBilling 0.7.2가 HTTP API 경로를 통해 제공된 Twig 표현식을 렌더링하는 반면, FOSSBilling 0.8.0은 동일한 API 호출을 노출하지 않음을 보여줍니다.

이 실습은 모든 FOSSBilling 템플릿 렌더링 기능을 테스트한다고 주장하지 않습니다. CVE-2026-28496은 또한 애플리케이션 내부에서 사용 가능한 템플릿 렌더링 기능과 같은 다른 Twig 렌더링 컨텍스트와 관련이 있습니다.

이 실습은 완전한 인증되지 않은 원격 코드 실행 체인을 시연하지 않습니다. 이는 로컬 FOSSBilling 0.7.2 타겟에서 관찰된 인증되지 않은 HTTP 동작을 검증하고 FOSSBilling 0.8.0과 비교합니다. 전체 공개 체인은 여기에 표시된 안전한 Twig 표현식 검증을 넘어 추가적인 API 권한 부여 동작을 포함합니다.

이 실습은 다음을 시연하지 않습니다:

* 원격 명령 실행,
* 자격 증명 추출,
* 데이터베이스 덤프,
* 확장 프로그램 설치,
* 임의 파일 쓰기,
* 지속성,
* 웹 셸 업로드,
* 외부 콜백,
* 비실습 시스템에 대한 공격,
* 또는 사후 침해 활동.

## 근본 원인 요약

CVE-2026-28496의 근본 원인은 안전하지 않은 Twig 템플릿 렌더링입니다.

FOSSBilling은 동적 템플릿을 렌더링하기 위해 Twig를 사용합니다. 취약한 버전에서는 제공된 템플릿 문자열이 충분한 샌드박스 제한 없이 Twig 렌더링 로직에 전달될 수 있습니다.

취약한 동작은 다음과 같이 요약할 수 있습니다:```text
Input template string
→ FOSSBilling API receives _tpl
→ System\Api\Admin::string_render() reads _tpl
→ System\Service::renderString() receives the template string
→ Twig creates a template from the supplied string
→ Twig evaluates the expression
→ rendered output is returned in the HTTP response

이 무해한 템플릿 표현식에 대해:```twig {{ 7*7 }}

취약한 대상이 표현식을 평가하고 반환합니다:```text
49

보안 문제는 산술 평가에만 국한되지 않습니다. 산술 평가는 이 랩에서 사용되는 안전한 가시적 신호일 뿐입니다.

더 보안에 민감한 문제는 샌드박스 처리되지 않은 Twig 템플릿이 템플릿 컨텍스트에 노출된 객체와 메서드에 접근할 수 있다는 점입니다. 공개 연구에서는 적절한 템플릿 컨텍스트 객체가 있을 때 Twig 템플릿 실행이 의존성 주입 컨테이너를 포함한 애플리케이션 내부에 도달할 수 있는 더 높은 영향력을 가진 경로를 설명합니다.

단순화된 취약 모델은 다음과 같습니다:```text Template renderer → unsandboxed Twig expression → method/object access may be possible → application internals may become reachable → sensitive services may become reachable

FOSSBilling 0.8.0에서 패치된 설계는 취약한 동작을 강화합니다. 이 실습에서는 패치된 대상이 더 이상 테스트된 API 호출을 노출하지 않습니다:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}

보안 교훈은:```text Template engines must not render user-controlled template strings in a privileged application context unless strict authorization and sandbox boundaries are enforced.

## 소스 코드 분석

취약한 HTTP 동작은 FOSSBilling 0.7.2의 소스 코드 경로에 의해 뒷받침됩니다.

API 메서드는 요청 데이터에서 `_tpl`을 받아 시스템 서비스 렌더러로 전달합니다.

관련 취약 진입점:```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);
}

중요한 데이터 흐름은 다음과 같습니다:```text HTTP request body → _tpl → System\Api\Admin::string_render() → System\Service::renderString()

In FOSSBilling 0.7.2, `renderString()` attempts to load the supplied value as a template name. If that fails, it treats the supplied value as a template string and passes it into `createTemplateFromString()`.

Simplified vulnerable flow:```php
public function renderString($tpl, $try_render, $vars)
{
    $twig = $this->di['twig'];

    try {
        $template = $twig->load($tpl);
        $parsed = $template->render($vars);
    } catch (\Exception) {
        // $twig->load throws an exception when $tpl is a raw template string
        $parsed = $this->createTemplateFromString($tpl, $try_render, $vars);
    }
도구 다운로드