cookie
쿠키로 인증 상태를 관리하는 간단한 로그인 서비스
admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있음
* [Dreamhack] Exercise: Cookie
# 문제 목표 및 기능 요약
- 해당 문제의 목표는 관리자 권한을 획득해 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이 "admin"일 경우 FLAG를 출력
# 엔드포인트: /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가 동일하지 않은 경우
GET
- username과 password를 입력할 수 있는 로그인 페이지를 제공
POST
- 이용자가 입력한 username과 password 입력 값을 users 변숫값과 비교
- users 변수가 선언된 코드: 손님 계정의 비밀번호는 'guest', 관리자 계정의 비밀번호는 파일에서 읽어온 FLAG임
try:
FLAG = open('./flag.txt', 'r').read() # flag.txt 파일로부터 FLAG 데이터를 가져옴.
except:
FLAG = '[**FLAG**]'
users = {
'guest': 'guest',
'admin': FLAG # FLAG 데이터를 패스워드로 선언
}
# 취약점 분석
- 이용자의 계정을 나타내는 username 변수가 요청에 포함도니 쿠키에 의해 결정되어 문제가 발생
- 쿠키는 클라이언트의 요청에 포함되는 정보로, 이용자가 임의로 조작할 수 있음
- 서버는 별다른 검증 없이 이용자 요청에 포함된 쿠키를 신뢰하고, 이용자 인증 정보를 식별하기 때문에 공격자는 쿠키에 타 계정 정보를 삽입해 계정을 탈취할 수 있음
@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" 문자열로 조작해야 함
- username을 "admin"으로 변경해 서버에 요청하면 다음과 같이 FLAG를 획득할 수 있음
# 마치며
- Cookie 문제를 통해, 서버가 검증 없이 쿠키를 신뢰하고 인증 정보를 식별할 때 발생할 수 있는 문제점에 대해서 알아봄
- 실습을 통해 해당 취약점을 이용하여 다른 계정의 권한을 획득할 수 있었음
> 위와 같은 문제점은 세션을 통해 해결할 수 있음
- 세션은 인증 정보를 서버에 저장하고, 랜덤한 키를 클라이언트에게 발급함
- 클라이언트는 해당 키를 포함해 서버에게 요청하고, 서버는 지정한 세션 키와 대응하는 클라이언트인지 확인하므로 안전한 서비스를 구현할 수 있음
'War Game & CTF > Dreamhack' 카테고리의 다른 글
[Dreamhack] xss-2 (0) | 2022.02.12 |
---|---|
[Dreamhack] xss-1 (0) | 2022.02.11 |
[Dreamhack] funjs (0) | 2022.01.31 |
[Dreamhack] session-basic (0) | 2022.01.24 |
[Dreamhack] Carve Party (0) | 2022.01.23 |