본문 바로가기
Web

Exercise: Cookie

by Anatis 2021. 12. 7.

쿠키에 대한 이해를 위해 드림핵 워게임 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

댓글