컴소니/보안

[웹 해킹] Dreamhack xss-1(Level 1)

금소니 2023. 8. 1. 17:45
반응형

#259

1. 개요

워게임 명 : xss-1

난이도 : Level 1

관련 개념 : Javascript, XSS, Cookie

문제 : XSS 취약점을 이용하여 FLAG 값 획득

XSS 강의에 포함된 워게임입니다.

2. 소스 코드 확인

1) HTML

소스코드에는 html 문서가 포함되어 있었고 어떻게 구현되어 있는지 확인이 필요해 보였습니다.

 

1-1) base.html

1-2) index.html

페이지를 분기하는 소스로 vul(xss) page를 클릭하였을때 스크립트가 실행되어 alert(1) 창을 띄웁니다.

1-3) memo.html

1-4) flag.html

파라미터를 입력받는 페이지입니다.

2) python

2-1) 초기 선언 부분

#!/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**]"

2-2) read_url 함수

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

2-3) check_xss

def check_xss(param, cookie={"name": "name", "value": "value"}):
    #check_xss는 read_url함수 호출하여 vuln 엔드포인트 접속
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
    return read_url(url, cookie)

2-4) app.route("/")

#render_template : flask에서 제공하는 함수로 templates에 저장된 html을 불러올 때 사용하는 함수
@app.route("/")
def index():
    return render_template("index.html")

2-5) app.route("/vuln")

#사용자가 입력한 param 값을 출력
#필터 없이 그대로 요청 받은 내용을 그대로 출력
@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return param

2-6) app.route("/flag", methods["GET", "POST"])

@app.route("/flag", methods=["GET", "POST"])
def flag():
    #이용자에게 URL을 입력받는 페이지를 제공
    if request.method == "GET":
        return render_template("flag.html")
    elif request.method == "POST":
        param = request.form.get("param")
        #파라미터 값과 쿠키에 FLAG를 포함해 check_xss 함수 호출
        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>'

2-7) app.route("/memo")

memo_text = ""

#사용자가 요청한 내용을 메모로 작성하여 출력
#여기는 render_template를 통해 출력하기 때문에 취약하지 않음
@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)

2-8) 서비스 실행

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

3. 웹 화면 확인

앞에서 소스를 분석했을때처럼 /vuln, /memo, /flag 경로가 존재하는 웹 서비스였습니다.

 

1) /vuln

index.html 소스에서 /vuln 링크를 클릭했을 때 아래와 같이 alert 창이 뜨도록 스크립트를 작성했었습니다.

그 결과, 스크립트가 실행되었고 해당 경로는 취약하다고 볼 수 있습니다.

2) /memo

여기는 메모가 입력되어 저장되는 경로로 링크를 클릭할 때 마다 hello 문구가 추가됩니다.

3) /flag

이 곳이 저희가 실제 테스트하여 flag 값을 얻을 경로입니다.

 

4.  문제 풀이

1) 요구사항 파악

취약한 페이지의 경우 /vuln 페이지고 /flag 링크에서 이를 이용하여 flag값을 얻으려고 합니다.

flag 값은 서버 로컬 경로의 flag.txt 파일에 존재하고 /flag 경로에 파라미터를 입력하면 cookie 값으로 flag 값을 저장합니다.

이것을 /memo 경로에 출력하면 됩니다.

 

2) 메모페이지 출력 테스트

flag 값을 확인하기 위해서는 /memo 경로에 어떻게 출력되는지 알아야하기 때문에 확인해보도록 하겠습니다.

GET 방식으로 URL에 데이터를 입력되면 출력되는 방식입니다.

hello 대신 여러 데이터를 입력하면 출력되는 것을 확인하실 수 있습니다.

 

3) flag 값 출력하기

이제 어떻게 출력하는지 알게 되었으니 본격적으로 flag 값을 출력해보도록 하겠습니다.

flag 값은 쿠키에 저장되어 있으며, 쿠키를 /memo 경로에 출력하도록 요청을 보내면 됩니다.

/vuln 경로에서는 스크립트 구문이 실행되었기 때문에 아래와 같이 작성하여 요청을 보냅니다.

 

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

 

보시면 해당 웹 서버의 /memo 경로에 쿠키 값(document.cookie)을 입력한다는 스크립트입니다.

그럼 위와 같이 good이란 알림창이 뜨면서 /memo경로로 가게되면 flag 값을 확인할 수 있습니다.

 

해당 게임의 경우 강의에서 내용을 다루고 있어 쉽게 풀 수 있었습니다.

이 공격을 응용한다면 XSS 취약점을 찾아내는데 큰 도움이 될 것으로 보입니다.

반응형