< 문제 >
https://dreamhack.io/wargame/challenges/269
username = 'admin'으로 로그인 해 FLAG를 획득하는 문제이다 .
< 풀이 >
@app.route("/vuln")
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
xss 공격을 유발하는 문자들은 필터링되고 있지만, csrf를 유발하는 < , > 등은 필터링 되지 않는다.
@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", "")
session_id = os.urandom(16).hex()
session_storage[session_id] = 'admin'
if not check_csrf(param, {"name":"sessionid", "value": session_id}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
1. session_id = os.urandom(16).hex() : 임의의 세션 아이디 생성
2. session_storage[session_id] = 'admin' : 해당 세션 아이디의 값이 'admin'이 된다.
@app.route("/change_password")
def change_password():
pw = request.args.get("pw", "")
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
users[username] = pw
return 'Done'
/change_password?pw="변경할 값" admin의 pw 가 입력한 값으로 정해지게 된다.
< 참고 >