SSTI 및 코드 인젝션을 위한 오류 기반(Error-Based) 및 부울 오류 기반(Boolean Error-Based) 블라인드 기법을 소개하는 백서입니다. 여섯 가지 프로그래밍 언어에 대한 범용 페이로드와 SSTImap에의 통합을 포함합니다.
[!NOTE] 이 백서는 SSTImap 버전 1.3.1을 출시하기 전에 발표한 결과를 바탕으로 한 두 번째 버전입니다. 향후 개선 사항은 추후 연구 버전 1.2 형태로 이 형식에 맞게 조정될 예정입니다.
일부 취약점 카테고리는 처음 보기에는 잘 알려져 있고 다소 명확해 보일 수 있습니다. 해당 취약점에 대한 모든 가능한 기법이 알려져 있어서 드문 경우에만 페이로드가 발견될 것처럼 보일 수 있습니다. 서버 측 템플릿 인젝션(SSTI)과 코드 인젝션은 종종 그런 잘 알려진 카테고리로 간주됩니다.
때로는 이러한 취약점에 대해 이름만으로 설명되는 새로운 기법이 등장하기도 합니다. 많은 연구자들은 그 기법 역시 잘 알려져 있거나 심지어 사용해 본 적이 있다고 생각할 수 있지만, 실제로는 그 기법이 연구, 설명 또는 범용 페이로드 없이 흔히 알려진 이름으로만 존재할 수 있습니다. 매우 특수한 경우에 대한 페이로드와 함께 몇 번 언급될 수 있지만, 실제로 테스트되지는 않았고 그 기법의 실제 잠재력은 수년간 발견되지 않을 수 있습니다.
본 연구에서는 코드 인젝션과 SSTI를 위한 두 가지 기법인 Error-Based(오류 기반) 및 Boolean Error-Based Blind(블리언 오류 기반 블라인드)를 소개합니다. 저는 여섯 가지 프로그래밍 언어(Python, PHP, Java, Ruby, NodeJS, Elixir)에 대한 코드 인젝션 및 SSTI 페이로드를 제공할 것입니다. 또한 블라인드 인젝션조차 신속하게 탐지할 수 있는 범용 탐지 페이로드를 제공할 것입니다.
본 연구의 전체 타임라인을 초기의 단서부터 최종 결론까지 제공하겠습니다. 또한 이 연구에서 다루지 않은 프로그래밍 언어 및 템플릿에 대한 새로운 페이로드를 만드는 과정도 살펴보겠습니다.
본 연구에서는 새로운 기법의 실제 적용 사례를 보여주고 추가 연구가 가능한 영역을 공유하겠습니다. 제공된 모든 페이로드는 실제 애플리케이션에서 취약점을 탐지하고 악용하는 데 사용할 수 있습니다. 또한 제공된 모든 페이로드는 오픈소스 도구 SSTImap에 추가되어, 이 연구 결과를 실제 대상에 더 쉽게 적용할 수 있도록 했습니다.
서버 측 템플릿 인젝션 취약점은 템플릿 엔진이 서버 측 렌더링에 사용되는 동적 웹사이트에서 발생하며, 신뢰할 수 없는 사용자 입력이 템플릿 엔진에 의해 처리되기 전에 템플릿에 삽입될 때 발생합니다. 악의적인 공격자는 유효한 템플릿 구문을 삽입할 수 있으며, 이 구문은 페이지 렌더링 중에 템플릿 엔진에 의해 처리됩니다. 많은 템플릿 엔진은 어느 정도의 코드 실행 기능을 제공하며, 이는 종종 대상 서버에서 원격 코드 실행(RCE)으로 이어집니다. 본 연구는 악용 시 그러한 기능을 제공하는 템플릿 엔진에 초점을 맞추고 있습니다.
SSTI 취약점은 2015년부터 알려져 왔으며, 그동안 정보 유출, 필터 우회 및 샌드박스 탈출을 위한 많은 페이로드가 발견되었습니다. 그럼에도 불구하고 대부분의 페이로드는 결과를 페이지에 직접 렌더링하거나 코드 실행 자체의 사실에 초점을 맞추며, 해당 코드가 생성한 결과는 무시합니다.

또 다른 잘 알려진 SSTI 기법은 시간 기반 블라인드로, 실행된 셸 명령에 지연을 추가하는 방법입니다. 이 기법은 주입된 코드 실행의 성공 여부를 판단할 수 있지만, OS 명령 실행을 위한 페이로드를 추측해야 하므로 연구자에게 알려지지 않은 템플릿 엔진에서 블라인드 SSTI를 탐지하기 어렵게 만듭니다.

SSTI 취약점 클래스와 두 가지 알려진 악용 기법은 2015년 James Kettle에 의해 발견되었습니다. 이 기법들은 그의 연구 "Server-Side Template Injection: RCE For The Modern Web App" 에 매우 자세히 설명되어 있습니다. [^1] 그 후 10년 동안 새로운 악용 기법은 문서화되지 않았습니다. 2023년에야 하나의 탐지 기법이 발견되었는데, 이는 다국어(polyglot) 페이로드를 사용하여 여러 템플릿 엔진을 동시에 테스트하는 방법입니다. 이 기법은 Maximilian Hildebrand에 의해 발견되었으며, 그의 연구 "Improving the Detection and Identification of Template Engines for Large-Scale Template Injection Scanning" 에 설명되어 있습니다. [^2] 이 기법은 최소한의 요청으로 템플릿 엔진을 식별하는 데 초점을 맞추고 있지만, 간단한 인젝션 컨텍스트에서만 작동합니다.

PHP, NodeJS, Python과 같은 해석형 프로그래밍 언어를 기반으로 하는 대부분의 템플릿 엔진은 해당 프로그래밍 언어의 표현식을 직접 평가할 수 있습니다. 이 기능을 통해 템플릿 태그의 올바른 형식으로 감싸서 더 광범위한 코드 인젝션 취약점 카테고리에 대한 페이로드를 사용할 수 있습니다.
코드 인젝션은 SSTI 없이도 발생할 수 있으며, 신뢰할 수 없는 사용자 입력이 eval() 또는 유사한 위험한 함수에 도달할 때 발생합니다.
종종 코드 인젝션 악용은 해당 언어로 프로그래밍하는 것에 불과하다고 간주되므로,
기법과 페이로드는 특정 취약점 예시에 대해서만 문서화되며, 이는 대상 애플리케이션에 맞게 코드를 조정해야 합니다.
코드 인젝션과 SSTI에 대한 보다 보편적인 탐지 기법의 부재는 블라인드 코드 및 템플릿 인젝션에 대한 블랙박스 스캐닝의 비효율성을 초래합니다.
본 연구에서는 코드 인젝션과 SSTI를 위한 두 가지 새로운 기법과 여섯 가지 프로그래밍 언어에 대한 페이로드, 그리고 범용 탐지 페이로드를 제공할 것입니다. 제공되는 기법은 블라인드 SSTI 악용의 기능을 확장할 뿐만 아니라, 주입된 코드의 프로그래밍 언어를 추측하지 않고도 블라인드 코드 인젝션 및 SSTI 스캐닝을 가능하게 합니다.
본 연구에서 제공하는 페이로드는 실제 웹 애플리케이션의 실무적 침투 테스트를 목표로 합니다. 제시된 모든 페이로드는 SSTI 및 코드 인젝션 탐지를 위한 오픈소스 도구인 SSTImap [^3] 의 모듈에 통합되어 있습니다. 두 가지 새로운 기법과 해당 페이로드에 대한 지원은 버전 1.3.0에 추가되었습니다. 본 연구에서 제공되는 새로운 기법의 실제 적용을 위한 덜 일반적이고 더 구체적인 페이로드는 "extra" 모듈을 위한 전용 저장소 [^4] 에서 찾을 수 있는 추가 SSTImap 모듈에 통합되어 있습니다.
SSTImap 모듈용 페이로드를 개발하는 동안 저는 제한 사항과 발견점을 만났으며, 이는 본 연구에서 제시하는 기법으로 이어지는 단서 역할을 했습니다. 기존 기법을 사용하여 주입된 코드의 출력을 얻을 수 없는 다양한 SSTI 및 코드 인젝션 시나리오를 접했습니다. 이러한 제한 사항을 만나는 동안 출력을 얻기 위해 다양한 아이디어를 테스트했으며, 결국 본 연구에서 문서화된 두 가지 새로운 기법의 발견으로 이어졌습니다.
잠재적인 한계를 암시하는 첫 번째 단서는 Dust.JS 템플릿 엔진에 대한 페이로드를 업데이트하는 동안 접했습니다. 이 엔진은 구식으로 간주되며 버려진 것으로 보이며, 코드 실행은 2015년의 오래된 dustjs-helpers 버전에서만 가능했습니다. 이 엔진에 대한 SSTImap 모듈은 Tplmap [^5] 코드베이스에서 상속받았으며 개선은 낮은 우선순위 작업이었지만, 이 모듈은 간단한 로직 없는 템플릿 엔진의 경우 많은 오탐을 유발했습니다.

문제를 해결하기 위해 페이로드를 개선했지만, 템플릿 엔진과 그 페이로드가 저의 관심을 끌었습니다.
코드 인젝션은 if 블록의 조건 내에서 가능했으며, 이 조건은 직접 eval()에 전달되었습니다. [^6]
결과는 페이지에 표시되지 않았기 때문에, 반영형 SSTI의 경우에도 RCE는 항상 블라인드일 것으로 간주되었습니다.

당시에는 오래된 템플릿 엔진을 연구하여 새로운 페이로드를 만드는 것이 우선순위가 매우 낮았기 때문에, 출력을 얻을 수 있는 잠재적인 방법을 조사하지 않기로 결정했습니다.
두 번째 단서는 Twig 템플릿 엔진의 새로운 버전에 대한 페이로드를 개발하는 동안 접했습니다. 초기 버전에 대한 페이로드는 이미 수정되었기 때문에, 업데이트된 페이로드로 새 모듈을 만들기로 결정했습니다. Twig를 악용하는 더 현대적인 방법을 찾는 과정에서 CVE-2022-23614를 발견했으며, 이는 최신 버전에서 일반적인 페이로드 중 하나를 사용하여 샌드박스 우회를 허용했습니다. [^7]
새로운 SSTImap 모듈을 위해 저는 해당 샌드박스 우회 악용이 가능한 페이로드를 사용하기로 결정했는데, 이는 최신 페이로드로 악용 가능한 거의 모든 Twig 버전에서도 작동했기 때문입니다.
샌드박스 우회는 PHP 함수 이름을 포함하는 문자열을 |sort 필터의 매개변수로 전달하여 가능하며,
이로 인해 템플릿이 두 배열 요소를 인수로 하여 해당 함수를 호출하게 됩니다.
Dust.JS의 경우와 유사하게, 함수의 출력은 내부적으로 조건(이번에는 배열 정렬을 위한 조건)으로 사용되므로 템플릿 컨텍스트로 다시 전달되지 않습니다.
이러한 제한은 악용을 방해하지 않습니다. PHP의 system() 함수는 OS 명령 실행 결과를 웹 페이지에 직접 출력하기 때문에 템플릿 엔진을 우회하여 출력을 얻을 수 있기 때문입니다.
우회 기법이나 새로운 SSTI 악용 기법의 일부로 템플릿 엔진 내에서 출력을 얻을 가능성에 대해 궁금증이 생겼습니다. Twig용 새 모듈을 만드는 데 필요하지 않았기 때문에, 템플릿 내에서 인젝션 결과에 접근하기 위한 새로운 페이로드 개발에 시간을 할당하지 않기로 결정했습니다.

Node.JS 모듈 JSONPath Plus의 버전 10.3.0 이전에서 발견된 CVE-2025-1302 취약점은 jsonpath의 확장된 조건 구문 내에서 함수 생성자에 접근하여 임의의 JavaScript 코드를 주입할 수 있게 합니다. [^8] 저는 CVE-2025-1302의 서버 측 jsonpath 인젝션 경우에 대해 자동 탐지 및 악용을 위한 새로운 추가 SSTImap 모듈을 만들기로 결정했습니다.

Dust.JS와 마찬가지로 코드 인젝션은 조건 내에서만 가능했기 때문에 출력을 얻어 페이지에 렌더링할 직접적인 방법이 없었습니다. 그럼에도 불구하고 출력을 추출할 가능성을 조사하기로 결정했고, 이는 결국 본 연구에서 논의된 발견으로 이어진 세 번째 단서가 되었습니다.