쿠키에 대한 이해를 위해 드림핵 워게임 cookie 문제로 연습을 해볼 것이다. 이번 문제는 파이썬 Flask 프레임워크로 구현되어 있다.
문제 목표 및 기능
- / : 이용자의 username을 출력하고 관리자 계정인지 확인한다.
- /login : username, password를 입력받고 로그인한다.
서비스 분석
엔드포인트: /
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')
요청에 포함된 쿠키를 통해 이용자를 식별하고 만약 쿠키에 존재하는 username이 "admin"일 경우 FLAG를 출력한다.
엔드포인트: /login
login 페이지 코드
@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 변수 선언
try:
FLAG = open('./flag.txt', 'r').read() # flag.txt 파일로부터 FLAG 데이터를 가져옴.
except:
FLAG = '[**FLAG**]'
users = {
'guest': 'guest',
'admin': FLAG # FLAG 데이터를 패스워드로 선언
}
GET
username과 password를 입력할 수 있는 로그인 페이지를 제공한다.
POST
이용자가 입력한 username과 password 입력 값을 users 변숫값과 비교한다.
guest의 비밀번호는 guest, 관리자의 패스워드는 파일에서 읽어온 FLAG 값임을 알 수 있다.
취약점 분석
@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')
username 변수가 요청에 포함된 쿠키에 의해 결정되어 문제가 발생한다. 쿠키는 클라이언트의 요청에 포함되는 정보로, 이용자가 임의로 조작할 수 있다. 서버는 별다른 검증 없이 이용자 요청에 포함된 쿠키를 신뢰하고, 이용자 인증 정보를 식별하기 때문에 공격자는 쿠키에 타 계정 정보를 삽입해 계정을 탈취할 수 있다.
익스플로잇

guest로 로그인한 후 개발자 도구를 이용하여 cookie 값을 보면 guest로 되어있다. 이를 admin으로 변경해보자.

쿠키 값을 admin으로 변경하니 FLAG 값이 출력이 되었다.
'Web' 카테고리의 다른 글
Exercise: XSS (0) | 2021.12.07 |
---|---|
ClientSide: XSS (0) | 2021.12.07 |
Mitigation: Same Origin Policy (0) | 2021.12.07 |
HTTP/HTTPS (0) | 2021.12.07 |
웹 리소스 (0) | 2021.12.07 |
댓글