해당 문제의 목표는 관리자 권한을 획득해 FLAG를 획득하는 것.
아래에 코드는 index 페이지를 구성하는 코드이다.
@app.route('/') # / 페이지 라우팅
def index():
username = request.cookies.get('username', None) # 이용자가 전송한 쿠키의 username 입력값을 가져옴
if username: # username 입력값이 존재하는 경우
return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}') # "admin"인 경우 FLAG 출력, 아닌 경우 "you are not admin" 출력
return render_template('index.html')
아래 코드는 로그인 페이지를 구성하는 코드이다.
@app.route('/login', methods=['GET', 'POST']) # login 페이지 라우팅, GET/POST 메소드로 접근 가능
def login():
if request.method == 'GET': # GET 메소드로 요청 시
return render_template('login.html') # login.html 페이지 출력
elif request.method == 'POST': # POST 메소드로 요청 시
username = request.form.get('username') # 이용자가 전송한 username 입력값을 가져옴
password = request.form.get('password') # 이용자가 전송한 password 입력값을 가져옴
try:
pw = users[username] # users 변수에서 이용자가 전송한 username이 존재하는지 확인
except:
return '<script>alert("not found user");history.go(-1);</script>' # 존재하지 않는 username인 경우 경고 출력
if pw == password: # password 체크
resp = make_response(redirect(url_for('index')) ) # index 페이지로 이동하는 응답 생성
resp.set_cookie('username', username) # username 쿠키 설정
return resp
return '<script>alert("wrong password");history.go(-1);</script>' # password가 동일하지 않은 경우
아래는 현재 회원가입된 유저의 이름과 패스워드 정보이다.
users = {
'guest': 'guest',
'admin': FLAG
}
쿠키의 밸류가 username의 값으로 설정이 된다. 정말 위험한 것이 쿠키는 브라우저에 저장되기 때문에 브라우저에서 그 쿠키의 밸류만 admin의 밸류로 바꿔주고 요청한다면 서버에서는 인증정보는 클라이언트 선에서 끝났기 때문에 한치의 의심도 없이 admin의 권한을 주게 된다.
위에 코드를 보면 try문으로 에러를 판별하여 users에 동일한 username이 있는지 확인하고 key값을 이용하여 비밀번호를 pw에 대입한다.
키값의 의한 대로면 guest의 비밀번호는 guest이고 admin의 비밀번호는 FLAG라는 파일에서 가져올 수 있다.
하지만 우리는 FLAG.txt라는 파일을 볼 수 없다.
그러므로 쿠키의 밸류를 admin으로 바꾸주어서 서버에 관리자 권한으로 요청을 해보자
아래 guest 쿠키값의 밸류를
admin으로 바꾸어주고 서버에 재요청을 하게 되면
FLAG를 얻을 수 있다.