
기본적인 구조는 CSRF-1 과 비슷하나, 코드를 살펴보면, 추가된 페이지가 하나 존재한다.
@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'
이번 문제에서의 FLAG는 관리자의 계정으로 로그인 해야 하는데, 위와 같이 비밀번호를 변경할 수 있는 페이지가 추가되었다. 바꿀 비밀번호를 pw 파라미터를 통해 전달받으며, 이 페이지에 접근하는 사용자의 세션ID를 확인하여 인증된 사용자만이 비밀번호를 변경할 수 있다.
위에서 살펴본 /change_password 페이지는 session_storage에 저장되어있는 사용자 전용 페이지이다. 우리는 CSRF 공격을 통해 관리자 권한을 통해 관리자의 비밀번호를 변경해야 한다.
취약점은 CSRF-1와 같이 /vuln 페이지에서 꺽쇠를 포함한 다른 키워드에 대한 필터링이 없으므로 CSRF 공격을 수행할 수 있다.
/flag 페이지에서 admin의 session_id 가 저장되므로 공격 코드가 삽입된 /flag 페이지에서 admin의 pw의 변경하기 위해선 /change_password 페이지를 접근해야한다.
/flag 페이지를 방문하는 이용자가 /change_password 페이지로 요청을 전송하도록 공격 코드를 작성해야 하므로 아래와 같이 <img> 태그를 활용하여 작성한다.
<img src="/change_password?pw=1234">
pw는 원하는 비밀번호로 바꾸어 로그인할 수 있게 한다.
admin 계정의 세션ID를 가지고 /change_password 페이지에 접속하였기 때문에 비밀번호를 임의로 바꾸어 로그인 할 수 있었다.
