SWLUG/์›น ํ•ดํ‚น

[Dreamhack/๋“œ๋ฆผํ•ต] DOM XSS

waterproof 2023. 11. 5. 13:13

 

 


 


(1) ๋ฌธ์ œ ์‚ดํŽด๋ณด๊ธฐ

 

 

์ฒซ ํ™”๋ฉด์ด๋‹ค.

 

 

 

 

 

vuln(xss) page ๋ฅผ ๋ˆ„๋ฅด๋ฉด

 

์ด์™€ ๊ฐ™์€ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜์˜จ๋‹ค.

 

 

 

 

 

memo๋ฅผ ๋ˆ„๋ฅด๋ฉด

 

 

"hello"๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ์ ํžŒ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜์˜จ๋‹ค.

 

 

 

 

flag๋ฅผ ๋ˆŒ๋Ÿฌ๋ณด๋ฉด

 

 

์•„๋งˆ ๋‹ต์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ์–‘์‹์ด ๋‚˜์˜ค๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

 

 

 

 


(2) ๋ฌธ์ œ ํ’€์ด (์‹œ๋„)

 

 

 

๋จผ์ €, vuln(xss) page๋ฅผ ์‚ดํŽด๋ณด๊ฒ ๋‹ค.

 

 

์ด๋ฏธ์ง€ ํƒœ๊ทธ๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์ถ”์ธกํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

ctrl + u ๋ฅผ ๋ˆŒ๋Ÿฌ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด๋ณด์•˜๋‹ค.

 

 

 

url ์ฃผ์†Œ๋ฅผ ๋ณด๋‹ˆ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๊ฐ€ ์‚ฌ์šฉ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ฐธ๊ณ ๋กœ "%20"์€ ์ŠคํŽ˜์ด์Šค ํ•œ ์นธ์„ url ์ธ์ฝ”๋”ฉํ•œ ๊ฒฐ๊ด๊ฐ’์ด๋‹ค.

 

 

๋” ์ด์ƒ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์—†์–ด์„œ ๋‹ค๋ฅธ ํŽ˜์ด์ง€์— ๋Œ€ํ•ด์„œ๋„ ์•Œ์•„๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

 

 

 

 

 

 

 

memo ํŽ˜์ด์ง€๋ฅผ ๋‚˜๊ฐ”๋‹ค๊ฐ€ ๋‹ค์‹œ ๋“ค์–ด์˜ค๋ฉด ๋ฐฉ๋ฌธํ•œ ํšŸ์ˆ˜์— ๋”ฐ๋ผ "hello"๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ๋Š˜์–ด๋‚˜์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์•˜๋‹ค.

 

 

 

 

 

 

์ด๊ฒƒ์ €๊ฒƒ ์‚ดํŽด๋ณด๋‹ค๊ฐ€, url ์ฃผ์†Œ๊ฐ€ /memo?memo=hello ๋กœ ๋˜์–ด์žˆ๊ธธ๋ž˜,

/memo?memo=flag ๋ผ๊ณ  ์ž…๋ ฅํ•˜๊ณ  ์ด๋™ํ•ด๋ณด์•˜๋”๋‹ˆ ๋ฉ”๋ชจ์— "flag"๋„ ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 

 

 

 

๋งˆ์ง€๋ง‰์œผ๋กœ flag ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ์‚ดํŽด๋ณด๊ฒ ๋‹ค.

 

 

์ด ํ˜•์‹์€ 

 

 

์•„๊นŒ vuln(xss) page ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ์ด๋™ํ•˜๊ฒŒ ๋˜๋Š” ํŽ˜์ด์ง€์˜ url ์ฃผ์†Œ์™€ ํ˜•์‹์ด ๋™์ผํ•˜๋‹ค.

 

 

 

 

 

๊ทธ๋ž˜์„œ ๊ทธ๋Œ€๋กœ ๋„ฃ์–ด๋ดค๋”๋‹ˆ, "good"์ด๋ผ๋Š” ๋ฉ”์„ธ์ง€๊ฐ€ ์ ํžŒ ํŒ์—…์ฐฝ์ด ๋œจ๊ณ  ๋‹ค๋ฅธ ๋ณ€ํ™”๋Š” ์—†์—ˆ๋‹ค.

 

 

 

 

๋ฌธ์ œ ํŒŒ์ผ์„ ๋ฐ›์•„์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€๋ฅผ ์‚ดํŽด๋ณด์•˜๋‹ค.

 

์—ฌ๋Ÿฌ๊ฐ€์ง€ ํŒŒ์ผ์ด ๋“ค์–ด์žˆ๋Š” ํด๋”๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 

 

 

๊ทธ ์ค‘์— app.py๋ผ๋Š” ํŒŒ์ผ์ด ๋ˆˆ์— ๋„์—ˆ๋‹ค.

 

๋‚ด์šฉ์„ ์‚ดํŽด๋ณด์•˜๋‹ค.

 

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

app = Flask(__name__)
app.secret_key = os.urandom(32)
nonce = os.urandom(16).hex()

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:
        service = Service(executable_path="/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("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, name, cookie={"name": "name", "value": "value"}):
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}#{name}"
    return read_url(url, cookie)

@app.after_request
def add_header(response):
    global nonce
    response.headers['Content-Security-Policy'] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}' 'strict-dynamic'"
    nonce = os.urandom(16).hex()
    return response

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


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


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

        return f'<script nonce={nonce}>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, nonce=nonce)


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

 

 

์ด์™€ ๊ฐ™์€ ๋‚ด์šฉ์ด์—ˆ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ ํ•ด์„์„ ํ•  ์ค„ ๋ชจ๋ฅด๊ฒ ์–ด์„œ ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ๋‹ค.

 

 

 


 


(3) ๊ฐœ๋… ์ •๋ฆฌ

 

์šฐ์„  ๋ฌธ์ œ ์ด๋ฆ„์ด DOM XSS์ด๋‹ˆ, DOM XSS๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

 

 

 


DOM(Document object Model)

 

์›น์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด ์ค‘ ํ•˜๋‚˜์ธ HTML(Hyper Text Markup Language) ๋“ฑ์œผ๋กœ ์ž‘์„ฑ๋œ ๋ฌธ์„œ๋ฅผ ๊ณ„์ธต์œผ๋กœ ํ‘œํ˜„ํ•˜์—ฌ ๋ฌธ์„œ ๋‚ด์˜ ํ—ค๋“œ(Head), ํผ(Form)๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ณ€ํ˜•, ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ธํ„ฐ๋„ท ์‚ฌ์ดํŠธ์—์„œ ํšŒ์› ๊ฐ€์ž… ์‹œ ๋ฉ”์ผ ์ฃผ์†Œ๋ฅผ ์ž˜๋ชป ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜, ์ „ํ™”๋ฒˆํ˜ธ์— ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ๊ณ ์ฐฝ์ด ๋Œ€ํ‘œ์ ์ธ ์‚ฌ๋ก€์ด๋‹ค. DOM์— ์˜ํ•ด HTML๋กœ ์ž‘์„ฑ๋œ ๋ฌธ์„œ ๋‚ด์˜ ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ํ˜•ํƒœ์˜ ๊ฒ€์ฆ์ด๋‚˜ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค. ์ปดํŒŒ์ผ ์—†์ด ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ(Interpreter) ๋ฐฉ์‹์˜ ๋Œ€ํ‘œ์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ์ค‘ ํ•˜๋‚˜์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ(JavaScript)์—์„œ HTML๋กœ ์ž‘์„ฑ๋œ ๋ฌธ์„œ์— ์ ‘๊ทผํ•  ๋•Œ ์ฃผ๋กœ ์“ฐ์ธ๋‹ค.

[๋„ค์ด๋ฒ„ ์ง€์‹๋ฐฑ๊ณผ] DOM [Document Object Model] (๋‘์‚ฐ๋ฐฑ๊ณผ ๋‘ํ”ผ๋””์•„, ๋‘์‚ฐ๋ฐฑ๊ณผ)

 

 

DOM์˜ ๊ตฌ์กฐ

 

์ถœ์ฒ˜: ์œ„ํ‚ค๋ฐฑ๊ณผ


์›นํŽ˜์ด์ง€์˜ ๊ฐ์ฒด๋“ค์„ ์ฃผ๋กœ ํŠธ๋ฆฌ(Tree) ํ˜•์‹์˜ ๊ณ„์ธตํ™”๋œ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ํŠธ๋ฆฌ๊ตฌ์กฐ์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋…ธ๋“œ(Node)๋ผ๊ณ  ํ•œ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ HTML๋กœ ์ž‘์„ฑ๋œ ์›น ํŽ˜์ด์ง€๋ฅผ ๋กœ๋”ฉ(Loading)ํ•  ๋•Œ ํŠธ๋ฆฌ ๊ตฌ์กฐ์˜ ๊ฐ ๋…ธ๋“œ๋ฅผ ์ธ์‹ํ•ด์„œ ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ DOM์„ ํ˜•์„ฑํ•˜๊ฒŒ ๋˜๊ณ , ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋“ฑ์„ ์ด์šฉํ•ด์„œ ํ•ด๋‹น DOM์˜ ๋…ธ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ๊ณ„์ธต์  ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋ฆฌ ๊ตฌ์กฐ์˜ ๊ฐ ๋…ธ๋“œ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•ด์„œ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
[๋„ค์ด๋ฒ„ ์ง€์‹๋ฐฑ๊ณผ] DOM [Document Object Model] (๋‘์‚ฐ๋ฐฑ๊ณผ ๋‘ํ”ผ๋””์•„, ๋‘์‚ฐ๋ฐฑ๊ณผ)

 

 

DOM์˜ ์‚ฌ๋ก€


์ธํ„ฐ๋„ท ์›นํŽ˜์ด์ง€์— ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จ ๋˜๋Š” ๋Œ€ํ‘œ์ ์ธ ๊ธฐ๋Šฅ์ธ ํด๋ฆญ(Click)์˜ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด ํ…์ŠคํŠธ๋‚˜ ์ด๋ฏธ์ง€์— "onclick" ์ด๋ฒคํŠธ๋ฅผ ์ ์šฉํ•˜๊ณ , ์‹ค์ œ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์˜€์„ ๊ฒฝ์šฐ์—๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋“ฑ์œผ๋กœ ํด๋ฆญ์— ๋Œ€ํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

button id="click_button" onclick="Method_Invocation()"



ํ•ด๋‹น ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์˜€์„ ๋•Œ Method_Invocation()์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜์—์„œ๋Š” DOM์— ์žˆ๋Š” ํŠน์ • ๋…ธ๋“œ์˜ ์†์„ฑ์— ์ ‘๊ทผํ•ด์„œ ์›ํ•˜๋Š” ๋™์ž‘์„ ์ธํ„ฐํŽ˜์ด์Šค ํ˜•ํƒœ๋กœ ์ œ๊ณตํ•˜๊ฒŒ ๋œ๋‹ค.
[๋„ค์ด๋ฒ„ ์ง€์‹๋ฐฑ๊ณผ] DOM [Document Object Model] (๋‘์‚ฐ๋ฐฑ๊ณผ ๋‘ํ”ผ๋””์•„, ๋‘์‚ฐ๋ฐฑ๊ณผ)

 

 

 

 


XSS(Cross Site Scripting) ๊ณต๊ฒฉ

 

์‚ฌ์ดํŠธ ๊ฐ„ ์Šคํฌ๋ฆฝํŒ…(๋˜๋Š” ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฝํŒ…, ์˜๋ฌธ ๋ช…์นญ cross-site scripting, ์˜๋ฌธ ์•ฝ์–ด XSS)์€ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋งŽ์ด ๋‚˜ํƒ€๋‚˜๋Š” ์ทจ์•ฝ์ ์˜ ํ•˜๋‚˜๋กœ ์›น์‚ฌ์ดํŠธ ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์ด๊ฐ€ ์›น ํŽ˜์ด์ง€์— ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ์ทจ์•ฝ์ ์ด๋‹ค.

์ฃผ๋กœ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ฒŒ ๋˜๋Š” ์ „์ž ๊ฒŒ์‹œํŒ์— ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ด๊ธด ๊ธ€์„ ์˜ฌ๋ฆฌ๋Š” ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. ์ด ์ทจ์•ฝ์ ์€ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ ๋ฐ›์€ ๊ฐ’์„ ์ œ๋Œ€๋กœ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋‚˜ํƒ€๋‚œ๋‹ค. ์ด ์ทจ์•ฝ์ ์œผ๋กœ ํ•ด์ปค๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด(์ฟ ํ‚ค, ์„ธ์…˜ ๋“ฑ)๋ฅผ ํƒˆ์ทจํ•˜๊ฑฐ๋‚˜, ์ž๋™์œผ๋กœ ๋น„์ •์ƒ์ ์ธ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฃผ๋กœ ๋‹ค๋ฅธ ์›น์‚ฌ์ดํŠธ์™€ ์ •๋ณด๋ฅผ ๊ตํ™˜ํ•˜๋Š” ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋ฏ€๋กœ ์‚ฌ์ดํŠธ ๊ฐ„ ์Šคํฌ๋ฆฝํŒ…์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

 

 

 

XSS ๊ณต๊ฒฉ์˜ ์ข…๋ฅ˜

 

  • Stored XSS 
  • Reflected XSS
  • DOM based-XSS  โžก๏ธ ์ด ๋ฌธ์ œ์—์„œ ๋‹ค๋ฃฐ XSS ๊ณต๊ฒฉ
  • Universal XSS

 

 

 


DOM-BASED XSS

 

  • ํด๋ผ์ด์–ธํŠธ์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ DOM ํ™˜๊ฒฝ์„ ์ˆ˜์ •ํ•œ ๊ฒฐ๊ณผ ๊ณต๊ฒฉ ํŽ˜์ด๋กœ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋ฐฉ์‹
  • ํŽ˜์ด์ง€ ์ž์ฒด(HTTP ์‘๋‹ต)๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์ง€๋งŒ, ํŽ˜์ด์ง€์— ํฌํ•จ๋œ ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋“œ๋Š” DOM ํ™˜๊ฒฝ์—์„œ ๋ฐœ์ƒํ•œ ์•…์˜์ ์ธ ๋ณ€์กฐ๋กœ ์ธํ•ด ๊ณต๊ฒฉ ๊ตฌ๋ฌธ์ด ์‹คํ–‰๋จ
  • Stored์™€ Reflected๊ฐ€ ์„œ๋ฒ„ ์ธก ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ทจ์•ฝ์ ์œผ๋กœ ์ธํ•œ ๊ณต๊ฒฉ์ธ ๋ฐ˜๋ฉด, DOM-based XSS๋Š” ์„œ๋ฒ„์™€ ๊ด€๊ณ„ ์—†์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐœ์ƒ

 

 

 

 

[๊ณต๊ฒฉ ํ๋ฆ„]

 

 

์›น ๋ธŒ๋ผ์šฐ์ €์˜ ์‘๋‹ต ํŽ˜์ด์ง€์— ํฌํ•จ๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋™์ž‘

→ DOM ๊ฐ์ฒด ์‹คํ–‰

→ URL์— ํฌํ•จ๋œ ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ ๋™์ž‘

 

 

 

 

 

 


[4] ๋ฌธ์ œ ํ’€์ด

 

app.py

 

CSP๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ๊ณ  'strict-dynamic' ๊ฐ€ ๋ณด์ธ๋‹ค.

์ด๋Š” '์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ์— ์˜ํ•ด ๋™์ ์œผ๋กœ ์ถ”๊ฐ€๋œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ—ˆ์šฉํ•˜๋„๋ก ์ง€์‹œํ•˜๋Š” ๊ฒƒ'์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

 

์Šคํฌ๋ฆฝํŠธ ํƒœ๊ทธ์˜ id๋ฅผ name์œผ๋กœ ํ•œ ๋’ค #๋’ค๋กœ ์•…์„ฑ ์ฝ”๋“œ๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์ฟ ํ‚ค๋ฅผ ํƒˆ์ทจํ•˜๋ฉด ๋˜๋Š” ๋ฌธ์ œ๋ผ๊ณ  ํ•œ๋‹ค.

(์™œ ์ฟ ํ‚ค์— flag ๊ฐ’์ด ์žˆ๋Š” ๊ฒƒ์ธ์ง€๋Š” ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ๋‹ค.)

 

 

 

<script id="name"></script>

 

- param์œผ๋กœ id="name"์ธ <script> ํƒœ๊ทธ๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค.

 

 

#location.href='/memo?memo='+document.cookie;//

 

- name์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฑด๋„ค์ฃผ๋ฉด ๋œ๋‹ค

- ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ(nonce ๊ฐ’ ์ธ์ฆ๋œ) ์Šคํฌ๋ฆฝํŠธ์— ์˜ํ•ด ๋™์ ์œผ๋กœ ์ถ”๊ฐ€๋˜๋ฏ€๋กœ(using innerHTML) ์ „ํ˜€ ๋ฌธ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค

 

 

 

 

 

flag ๊ฐ’์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค! ๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ด๋„ ์–ด๋ ต๊ฒŒ ๋Š๊ปด์กŒ๋‹ค...

์›น์— ๋Œ€ํ•œ ๊ณต๋ถ€๋ฅผ ํ•˜๋‹ค๋ณด๋ฉด ๋‚˜์ค‘์— ์ด ๋ฌธ์ œ๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ดํ•˜๋Š” ๋‚ ์ด ์˜ค์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค...

 

 

 


[5] ์ฐธ๊ณ 

 

https://keyme2003.tistory.com/entry/dreamhack-DOM-XSS

 

[dreamhack] DOM XSS

๋ฌธ์ œํ’€์ด @app.after_request def add_header(response): global nonce response.headers['Content-Security-Policy'] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}' 'strict-dynamic'" n

keyme2003.tistory.com

 

https://velog.io/@jckim22/%EB%B9%A1%EA%B3%B5%ED%8C%9F-7%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C-19-%EB%93%9C%EB%A6%BC%ED%95%B5-%EC%9B%8C%EA%B2%8C%EC%9E%84-DOM-XSS

 

[WARGAME] ๋“œ๋ฆผํ•ต ์›Œ๊ฒŒ์ž„ - DOM-XSS

๋จผ์ € ์•„๋ž˜ ์„œ๋ฒ„ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.DOM XSS๋ผ ๊ทธ๋Ÿฐ์ง€ ๊ธฐ๋ถ„ ํƒ“์ธ์ง€ ๋ชจ๋ฅด๊ฒŒ ์ฝ”๋“œ๊ฐ€ ๋ณ„๊ฒŒ ์—†์–ด ๋ณด์ธ๋‹ค.vuln.htmlDOM-XSS๋Š” ๋ธŒ๋ผ์šฐ์ € ๋‹จ์—์„œ ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๋ž˜๋„ ์›น ํŽ˜์ด์ง€์— ์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ํ•ต์‹ฌ์ผ ๊ฒƒ์ด

velog.io

 

https://minseosavestheworld.tistory.com/148

 

[Dreamhack Wargame] DOM XSS

Document Object Model (DOM) - ์›น ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ธํ„ฐํŽ˜์ด์Šค - ์›น ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•œ ์›น ๋ฌธ์„œ๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ํŒŒ์‹ฑ๋˜์–ด DOM์œผ๋กœ ํ‘œํ˜„๋จ - ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์›น ๋ฌธ์„œ์— ์ ‘๊ทผํ•  ๋•Œ์—๋Š” DOM์„ ํ†ตํ•ด ์ ‘

minseosavestheworld.tistory.com

 

 

'SWLUG > ์›น ํ•ดํ‚น' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[xss-game] Level 5: Breaking protocol  (3) 2023.11.06
[Dreamhack/๋“œ๋ฆผํ•ต] xss-1  (0) 2023.11.05
[los.rubiya.kr] orc  (1) 2023.10.07
[los.rubiya.kr] goblin  (1) 2023.10.06
[los.rubiya.kr] cobolt  (0) 2023.10.06