Handlebars SSTI란?
Handlebars SSTI는 서버 측 템플릿 엔진인 Handlebars에서 발생할 수 있는 보안 취약점입니다. 이 취약점은 공격자가 서버에서 실행되는 코드를 주입할 수 있게 하여, 원하지 않는 명령어 실행이나 데이터 유출을 초래할 수 있습니다.
💡 이 취약점은 4.0.14 이전 버전에서만 발생합니다.
배경
SSTI
SSTI는 Server-Side Template Injection의 약자로, 템플릿 엔진에 악의적인 구문을 삽입하여 공격이 성공할 경우 RCE, LFI 등을 실행할 수 있습니다.
Handlebars
Handlebars는 Node.js 기반 프레임워크에서 사용되는 템플릿 엔진입니다.
Payload
Payload Explain
1. "s" 문자열을 변수화
{{#with ... as |alias|}}
는 Handlebars.js에서 제공하는 블록 헬퍼로, "s"라는 문자열을 string이라는 이름으로 변수화합니다. 이 변수는 이후 조작 대상이 됩니다.
2. split 객체를 conslist라는 변수로 할당
split
은 JavaScript에서 문자열을 특정 구분자를 기준으로 나누는 메서드입니다. 이 템플릿에서는 이를 통해 리스트(배열)처럼 보이는 객체를 생성합니다. 생성된 리스트는 conslist
라는 이름으로 저장되며, 이후 객체 내부 메서드(push, pop)를 이용해 조작됩니다.
3. pop 메서드 호출
pop
메서드는 배열의 마지막 요소를 제거하고 반환합니다. 리스트가 비어있으므로 아무것도 하지 않음
4. constructor 객체에 접근
lookup
는 특정 객체의 속성이나 메서드에 접근하는 헬퍼입니다. 여기서 string.sub
는 string 객체에서 sub 메서드를 참조한 것입니다. constructor
는 JavaScript의 모든 객체에 존재하는 기본 속성으로, 생성자 함수에 접근하는 데 사용됩니다. 결과적으로 이 코드는 JavaScript의 Function constructor를 참조하여 임의 코드 실행이 가능하게 만듭니다.
5. 시스템 명령어 정의
여기서 push를 통해 리스트에 시스템 명령어를 포함하는 문자열을 삽입합니다. 명령어 내용:
require('child_process')
는 Node.js에서 시스템 명령어를 실행할 수 있는 모듈을 로드합니다. .exec(...)
는 시스템 쉘 명령어를 실행하는 메서드로, 여기서는 서버에서 특정 파일(/home/carlos/morale.txt)을 삭제하는 명령어(rm)를 실행하려고 합니다.
6. 템플릿 반복문 실행
#each
는 Handlebars.js에서 제공하는 반복문으로, 리스트(conslist)의 모든 요소를 순회합니다. string.sub.apply(0, codelist)
는 string.sub
가 문자열 메서드 Function을 참조한 것으로, apply
를 사용해 실행 시 인자를 리스트로 전달합니다. 이를 통해 조작된 codelist를 실행 컨텍스트에 적용하여 JavaScript 코드를 실행하려 합니다. 최종적으로 {{this}}
는 템플릿 내에서 현재 컨텍스트를 출력하거나 실행하는 데 사용됩니다.
공격자는 템플릿 엔진이 제공하는 헬퍼와 메서드 체인 조작 기능을 이용해 JavaScript의 Function constructor에 접근하고, 이를 통해 코드를 실행합니다.