컴소니/보안

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

금소니 2023. 8. 7. 17:44
반응형

#260

1. 개요

워게임 명 : xss-2

난이도 : Level 1

관련 개념 : Javascript, XSS, Cookie

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

* 이전에 풀이하였던 xxs-1 워게임의 다른 버전 취약점입니다.

마찬 가지로 XSS 강의에 포함된 워게임입니다.

2. 소스 코드 확인

xxs-1 워게임의 소스코드와 모두 동일하며, vul.html만 추가되었습니다.

 

1) HTML

1-0) vul.html

새로 추가된 html파일로 /vul 경로에 파라미터를 입력하였을때 해당 파라미터는 innerHTML을 이용하여 동작하도록 내용을 추가하였습니다.

1-1) base.html

1-2) index.html

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

앞의 vul.html을 보면 입력된 파라미터의 경우 innerHTML로 동작하게 되어 <script>의 경우 더 이상 실행되지 않습니다.

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. 웹 화면 확인

xss-1과 동일하게 구성된 웹 서비스입니다.

 

1) /vuln

xxs-1의 경우에는 alert 이벤트가 발생했었지만 이번의 경우에는 아무런 반응이 없습니다.

2) /memo

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

3) /flag

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

4.  문제 풀이

1) 요구사항 파악

xss-1과 구성은 같지만 더 이상 /vuln 페이지에서 <script>를 이용한 스크립트 삽입 공격이 어려울 것으로 보입니다.

따라서 <script>가 아닌 innerHTML를 이용하여 XSS 공격을 시도하여 flag 값을 얻어야할 것 같습니다.

 

2) xss-1에서 사용한 요청 이용하기

먼저 xss-1에서 사용한 요청을 한 번 테스트해보도록 하겠습니다.

 

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

 

입력 후에 메모를 확인한 결과 스크립트 문장이 정상적으로 실행되지 않았습니다.

3) 다른 방법을 이용하여 flag값 알아내기

일단 기존의 취약점을 이용하여 공격이 시도되지 않는단는 것을 알게되었으니 다른 방법을 통해 flag 값을 알아보도록 하겠습니다.

우선 flag 경로를 보면 마찬가지로 /vuln 경로의 파라미터를 이용하여 공격을 시도해야합니다.

소스를 분석한 결과 innerHTML을 이용하고 있으므로 이를 이용하여 공격을 시도한다면 flag 값을 얻을 수 있습니다.

 

파라미터를 통하여 임의의 이미지를 삽입하고 이미지 로드 실패 시 사용되는 이벤트를 통하여 공격을 시도해보도록 하겠습니다.

먼저 /vuln 경로를 이용하여 테스트를 해보도록 하겠습니다.

제가 사용할 코드는 아래와 같습니다.

 

/vuln?param=<img src = "x"  onerror="alert(1)">

입력했을 때 위와 같이 alert 이벤트를 발생하고 있습니다.

따라서 이를 이용한다면 xss-1과 비슷한 방법으로 flag 값을 얻을 수 있을 것으로 보입니다.

 

그럼 xss-1에서 이용하였던 코드와 이를 조합하여 시도해보도록 하겠습니다.

 

<img src = "x" onerror="location.href='/memo?memo=' + document.cookie">

그 결과 flag 값을 얻을 수 있었습니다.

 

이제부터가 뭔가 본격적인 웹 해킹 시작인 것 같아 보입니다.

부지런히 공부해서 웹 취약점을 착착 발견할 수 있을 정도의 실력이 되기를 바래봅니다.

반응형