본문 바로가기

Security

[wargame] xss-1

반응형

https://dreamhack.io/wargame/challenges/28/

 

xss-1

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다. XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. Reference Client-side Basic

dreamhack.io

#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
import urllib
import os

app = Flask(__name__)
app.secret_key = os.urandom(32)

try:
    FLAG = open("./flag.txt", "r").read()
except:
    FLAG = "[**FLAG**]"


def read_url(url, cookie={"name": "name", "value": "value"}):
    cookie.update({"domain": "127.0.0.1"})
    try:
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome("/chromedriver", options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get("http://127.0.0.1:8000/")
        driver.add_cookie(cookie)
        driver.get(url)
    except Exception as e:
        driver.quit()
        # return str(e)
        return False
    driver.quit()
    return True


def check_xss(param, cookie={"name": "name", "value": "value"}):
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
    return read_url(url, cookie)


@app.route("/")
def index():
    return render_template("index.html")


@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return param


@app.route("/flag", methods=["GET", "POST"])
def flag():
    if request.method == "GET":
        return render_template("flag.html")
    elif request.method == "POST":
        param = request.form.get("param")
        if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
            return '<script>alert("wrong??");history.go(-1);</script>'

        return '<script>alert("good");history.go(-1);</script>'


memo_text = ""


@app.route("/memo")
def memo():
    global memo_text
    text = request.args.get("memo", "")
    memo_text += text + "\n"
    return render_template("memo.html", memo=memo_text)


app.run(host="0.0.0.0", port=8000)

 

풀이

 

메인 화면이다.

 

vuln(xss) page를 클릭하면 아래와 같이 param으로 입력된 값이 그대로 들어간다.

script에 대한 필터링이 없어 자바스크립트 또한 동작한다.

 

memo를 클릭시에는 memo라는 파라미터에 들어가는 값이 영역에 추가되어 출력된다.

 

 

flag에서는 param값에 입력한 값으로 request를 보낼 수 있다.

소스를 분석해보면  flag에서 param값에 입력해서 submit 요청 시에 FLAG값을 쿠키에 심어서 127.0.0.1:8000 도메인으로 열린 브라우저에 저장하는 것을 확인할 수 있다.

그리고 flag에 입력한 param을 통해 완성된 url로 브라우저를 띄운다.

쿠키에 FLAG가 심겨진 시점은 이 때 이므로 url 즉 param에 입력한 값을 통해 memo에 기록을 남기면 된다.

(열린 browser는 해당 작업 완수 후에 종료되기 때문.)

<script>location.href="/memo?memo="+document.cookie</script> 를 전송하면 된다.

반응형

'Security' 카테고리의 다른 글

[Webhacking] business logic vulnerability  (0) 2021.09.27
[wargame] xss-2  (1) 2021.09.26
[wargame] csrf-2  (0) 2021.09.25
[Webhacking] file vulnerability  (0) 2021.09.24
[Webhacking] server side request forgery (SSRF)  (0) 2021.09.24