Write-Up
@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
@app.route("/admin/notice_flag")
def admin_notice_flag():
global memo_text
if request.remote_addr != "127.0.0.1":
return "Access Denied"
if request.args.get("userid", "") != "admin":
return "Access Denied 2"
memo_text += f"[Notice] flag is {FLAG}\n"
return "Ok"
/vuln 페이지를 구성하는 코드는 이용자가 전달한 param 파라미터의 값을 출력한다. 이 때, 이용자의 파라미터에 "frame", "script", "on" 세 가지의 악성 키워드가 포함되어 있으면 이를 '*' 문자로 치환한다.
( 키워드 필터링은 XSS 공격을 방지하기 위한 목적으로 존재하며, 본 문제의 의도는 XSS 공격이 아닌 CSRF 공격을 통해서 관리자의 기능을 수행하는 것이기 때문에 일부 키워드를 필터링 하였다고 한다. )
그리고 /admin/notice_flag 경로로 접근 시, 1차적으로 remote_addr이 127.0.0.1인지 비교한다. 그 후에, userid 매개변수의 값이 admin인지 확인한다. 모든 if 문을 통과하면, memo_text에 flag를 쓰게 된다. 그러므로, 아래 payload를 전달하여, memo 장에 flag를 쓰도록 만들면 된다.
payload
<img src="/admin/notice_flag?userid=admin">