암호(수학) 등.. 공부한 거 잊을거 같아서 만든 블로그

[Dreamhack] xss-1 본문

Dreamhack/Web

[Dreamhack] xss-1

h34hg0 2023. 4. 7. 16:18

문제


 

문제 파일 : app.py

더보기

app.py

#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
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:
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome("/chromedriver", 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)

 


풀이


 

/

 

문제 페이지에 접속하면 다음과 같은 화면이 나온다.

 

/vuln?param=<script>alert(1)</script>

 

vlun(xss) page 를 클릭하면 /vuln?param=<script>alert(1)</script> 로 이동하며, GET 요청에 param 파라미터에 스크립트가 삽입되어 위 이미지처럼 스크립트가 실행되는 것을 알 수 있다. 즉, /vuln 페이지는 xss 공격에 취약하다.

 

/memo?memo=hello

 

memo 페이지에 들어가보면 박스에 hello가 출력된다.

 

 

/memo?memo=hi

url에서 memo 파라미터의 값을 hi 로 바꾼 결과 박스안에 hello가 아닌 hi 가 적혀진 것을 볼 수 있다.

따라서 memo 페이지는 memo 파라미터의 값을 박스안에 출력해주는 페이지임을 알 수 있다.

 

 

/flag

 

/flag 페이지를 들어가면 위와같은 입력 폼이 나온다.

아무 값이나 넣고 제출을 누르면 아래의 이미지처럼  나온다.

 

제출 후 화면

 

param

 

이제 문제 코드를 봐보자.

 

app.py 코드에서 /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>'

 

GET 요청을 받으면 flag.html 을 보여주고, POST 요청이면  param의 값과 flag의 값을 check_xss 함수의 인자로 전달 한다.

 

check_xss 함수를 보자.

 

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)

 

url 변수에 param 값을 파라미터에 넣어  /vuln 페이지를 요청하는 url을 만들고, read_url 함수의 인자로 url, cookie 값을 넣어 반환 값을 리턴해준다.

여기서 param은 /flag 페이지에 입력폼에 입력한 값이고, cookie는 flag가 저장되어 있다.

 

read_url 함수는 웹 드라이버를 이용하여 url 과 cookie 값의 해당하는 페이지를 서버 로컬에서 접속하는 동작을 하는 함수이다.

따라서 입력폼에 입력한 값이 /vuln 페이지에 param 파라미터로 들어가서 접속하기 때문에 이를 통하여 xss 공격이 가능하다.

 

더보기

read_url

def read_url(url, cookie={"name": "name", "value": "value"}):
    cookie.update({"domain": "127.0.0.1"})
    try:
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome("/chromedriver", 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

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

 

<script>window.location.href = "/memo?memo=" + document.cookie</script> 를 /flag 페이지의 입력폼에 넣으면 

/vuln?parm=<script>window.location.href = "/memo?memo=" + document.cookie</script> 를 서버에 요청하게 되고,

/vuln페이지는 xxs에 취약하므로 스크립트가 그대로 실행된다. 

따라서 아래 이미지 처럼 memo 페이지에 flag 를 확인할 수 있다.

<script>window.location.href = "/memo?memo=" + document.cookie</script> 이 스크립트는  

"/memo?memo=" + document.cookie 로 이동하는 스크립트이다. /memo 페이지의 memo 파라미터는 박스에서 출력되어 보여지기 때문에 memo 파라미터의 값을 쿠키로 해서 flag가 출력 되게 했다.

 

flag

 

'Dreamhack > Web' 카테고리의 다른 글

[Dreamhack] csrf-1  (0) 2023.04.14
[Dreamhack] xss-2  (0) 2023.04.08
[Dreamhack] cookie  (0) 2023.04.04
[Dreamhack] session-basic  (0) 2023.04.04
[Dreamhack] funjs  (0) 2023.04.03