SSTI란?
공격자가 템플릿 구문을 이용해 악성 페이로드를 템플릿에 주입하고, 서버 측에서 실행되도록 하는 공격
-> 사용자의 입력이 데이터로서 템플릿에 전달되지 않고 템플릿 내에 직접 연결될 때 발생
이러한 SSTI는 서버 측에서 전달되고 평가되기 때문에, CSTI보다 훨씬 위험도가 높으며 서버의 민감한 파일을 읽거나 RCE와 같은 공격이 가능합니다.
템플릿 구문
SSTI 가능 여부는 아래와 같은 페이로드를 통해 확인해 볼 수 있습니다.
- {{9*9}}
- ${9*9}
- ${{9*9}}
- <%= 9*9 %>
- #{9*9}
웹 페이지에서 만약 파라미터 값을 그대로 출력하고 있다면 아래와 같은 방법으로 SSTI 가능 여부를 확인할 수 있지만
만약 그대로 출력하는 것이 아닌 변수를 통해 해당 변수의 값이 출력되는 환경에서는 아래와 같은 방법으로 SSTI 가능 여부를 확인할 수 있습니다.
이 경우를 추가적으로 설명하자면 우리가 SQL Injetcion에서 ' 를 이용해 쿼리를 조작하듯이 SSTI에서도 아래와 같은 코드를
{{ user.name }}
다음과 같이 조작하는 것 입니다.
{{ user.name }}{{7*7}}
에러 메시지로 템플릿 정보 획득
템플릿 엔진에 대한 정보가 없는 경우, 잘못된 템플릿 구문을 입력하였을 때 출력되는 에러 메시지로 어떤 템플릿을 사용하는지 확인할 수 있습니다.
아래는 Ruby기반 ERB 엔진에서 잘못된 구문을 입력하여 출력된 에러메시지로 해당 메시지에서 ERB 엔진이 사용되었음을 알 수 있습니다.
해당 포스팅의 실습은 모두 Burp Suite PortSwigger에서 진행된 내용입니다.
SSTI 실습 (파라미터 값을 그대로 출력시키는 경우)
Ruby의 ERB엔진을 사용 중인 환경에서 morale.txt 파일을 삭제하여 Lab을 클리어할 수 있는 문제입니다.
문제 접속 시 쇼핑몰 페이지가 열렸고,
상품을 클릭하였지만 해당 상품의 재고가 떨어졌다는 경고 문구가 출력되었습니다.
하지만 자세히 살펴보니 message라는 파라미터의 값이 그대로 출력되고 있다는 것을 알았고,
ERB 엔진에서 사용되는 템플릿 구문에 수학식을 포함시켰더니 49라는 결과가 출력되는 것을 통해 SSTI에 취약함을 확인하였습니다.
Ruby에서 사용되는 시스템 함수를 통해 ls 명령어를 실행시켜 morale.txt 파일이 존재함을 알게 되었고,
ls 대신 rm 명령어를 통해 해당 파일을 삭제하였더니 Lab을 클리어할 수 있었습니다.
SSTI 실습 (파라미터 값을 변수로 출력시키는 경우)
Tornado 템플릿에서 morale.txt 파일을 삭제하여 Lab을 클리어할 수 있는 문제입니다.
문제에서 제공받은 아이디와 비번으로 로그인을 하였더니, 이메일 변경과 원하는 닉네임을 고를 수 있는 기능을 사용할 수 있었습니다.
해당 페이지에서 닉네임을 선택하는 기능을 사용하면 위와 같이 댓글의 이름이 달라진다는 것을 알 수 있었고
이러한 요청을 통해 닉네임 변경이 이루어진다는 것도 알게 되었습니다.
해당 요청에 위와 같이 }}{{7*7 이라는 구문을 삽입해 결과를 확인하니
이런 식으로 닉네임 뒤에 7*7의 결과인 49가 출력되었다는 것을 알 수 있었고 SSTI가 가능하다는 것도 알 수 있었습니다.
문제에서 제공받은 템플릿의 정보로 토네이도 템플릿에 대해 찾아보았더니 파이썬 모듈을 불러올 수 있는 기능이 존재한다는 것을 알게 되었습니다. 이를 이용해 위와 같은 페이로드를 작성한다면 시스템 명령을 내릴 수 있겠다고 생각하였고
ls 대신에 morale.txt 파일을 삭제하는 명령어를 입력하고
url 인코딩을 진행하여 요청을 보냈더니
파일이 삭제되었다고 뜨면서 Lab을 클리어할 수 있었습니다.
SSTI 실습 (템플릿의 객체에 접근이 가능한 경우)
이번 문제에서는 템플릿에 대한 정보가 공개되지 않았으며 객체가 템플릿으로 전달되는 방식에 취약점이 존재한다는 정보와 로그인 아이디 비번을 제공받았으며 Secret key를 획득해야 Lab을 클리어 할 수 있습니다.
일단 제공받은 아이디와 비번을 이용해 로그인을 해주었더니
이렇게 상품의 설명을 직접 수정할 수 있는 권한이 생겼습니다. 그런데 해당 내용에 템플릿 구문이 들어가 있음을 알았고 템플릿을 통해 출력된다는 것도 알 수 있었습니다.
일단 아직 템플릿에 대한 정보가 없기 때문에 템플릿에 대한 정보를 얻기 위해 에러 메시지를 출력시키려 하였습니다. 처음에는 {{keshu}}로 작성해 보았더니 에러가 나타나지 않길래 다른 템플릿 표현식을 이용해 페이로드를 작성해 보았습니다.
그랬더니 오류가 출력되었고 해당 메시지에서 django 템플릿이 사용된다는 것을 알 수 있었습니다.
django 공식 문서를 찾아보던 중 SECRET_KEY에 대한 정보를 얻을 수 있었는데 settings.py 파일에 SECRET_KEY가 있다는 것을 확인할 수 있었습니다. 하지만 해당 파일에 어떤 식으로 접근해야 하며, 어떤 페이로드를 작성해야 할지는 모른 채 막막해하던 중...
한 블로그에서 settings라는 객체를 통해 접근하는 것을 볼 수 있었고, 바로 settings.DEBUG라는 페이로드를 주입해 보았습니다.
그랬더니 True라는 출력 결과가 나왔고 DEBUG 모드가 True로 설정되었다는 것을 알게 되었습니다.
다른 블로그도 살펴보았더니 DEBUG 모드가 활성화되어 접근이 가능하다면 SECRET_KEY에도 접근 가능할 것이라는 정보를 얻게 되었습니다.
DEBUG 대신 SECRET_KEY를 작성하여 결과를 확인했더니..
위와 같은 출력 결과가 반환되었고
이를 제출하여
Lab을 클리어할 수 있었습니다.
SSTI와 CSTI의 차이
두 공격 모두 Web Template Engine에서 이루어지는 공격이지만 Server Side와 Client Side 중 어떤 템플릿 엔진에서 이루어지는 지에 대한 차이가 존재합니다. 보통 CSTI는 클라이언트에서 이루어지는 공격으로 세션과 쿠키를 탈취는 것이 가능하지만, SSTI는 서버의 데이터에 접근할 수 있기 때문에 서버의 데이터를 훼손하거나, 서버를 장악할 수 있는 공격이 가능하기 때문에 CSTI보다 위험도가 조금 더 높은 공격이라 볼 수 있습니다. ( CSTI란? )
대응 방안
- 화이트 리스트 필터링, 블랙리스트 필터링 -> 사용자의 입력값 검증
- 템플릿에서 제공하는 기능을 통해 템플릿 자체에 영향을 줄 수 없도록 제한
- jinja의 rander_template(), Django의 escape 등
- 로직이 없는 템플릿 엔진 사용
- Mustache와 같은 템플릿 엔진은 로직을 거의 포함하지 않음
SSTI와 CSTI에 대해 공부하며 템플릿 엔진의 페이로드가 비슷하다고 하더라도, 템플릿 정보를 얻어 해당 템플릿에서 제공되는 여러 기능으로 데이터를 노출시키는 등의 공격이 가능하다는 것을 알게 되었습니다. Template Injection을 할 때 중요한 것은 그 템플릿에 대해 얼마나 알고, 그 템플릿에서 제공되는 기능을 얼마나 잘 활용해 공격을 하는지에 따라 취약점의 위험도가 달라질 수 있을 것이라 생각합니다.
'Web > Web Hacking' 카테고리의 다른 글
JWT(JSON Web Token) Attacks (0) | 2024.11.16 |
---|---|
CSTI (Client Side Template Injection) (0) | 2024.10.24 |
GraphQL Injection (2) | 2024.09.25 |
NoSQL Injection (0) | 2024.09.07 |
XXE External Entities (0) | 2024.09.06 |