NOT4DOG
방명록 RSS 태그 글쓰기 관리자
 
[CTF] Dreamhack session-basic 문제 Write-up
CTF Write-up 2022-01-23 18:07:59

반응형

문제) 쿠키와 세션으로 인증 상태를 관리하는 간단한 로그인 서비스입니다.
           admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다.

 

로그인 페이지와 함께 app.py 를 제공한다.

Main Page

#!/usr/bin/python3
from flask import Flask, request, render_template, make_response, redirect, url_for

app = Flask(__name__)

try:
    FLAG = open('./flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

users = {
    'guest': 'guest',
    'user': 'user1234',
    'admin': FLAG
}

session_storage = {
}


@app.route('/')
def index():
    session_id = request.cookies.get('sessionid', None)
    try:
        username = session_storage[session_id]
    except KeyError:
        return render_template('index.html')

    return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}')


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    elif request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        try:
            pw = users[username]
        except:
            return '<script>alert("not found user");history.go(-1);</script>'
        if pw == password:
            resp = make_response(redirect(url_for('index')) )
            session_id = os.urandom(32).hex()
            session_storage[session_id] = username
            resp.set_cookie('sessionid', session_id)
            return resp 
        return '<script>alert("wrong password");history.go(-1);</script>'


@app.route('/admin')
def admin():
    return session_storage


if __name__ == '__main__':
    import os
    session_storage[os.urandom(32).hex()] = 'admin'
    print(session_storage)
    app.run(host='0.0.0.0', port=8000)

 

문제에서 admin 계정으로 로그인 해야 FLAG를 확인할 수 있다고 설명 되어있다.

코드를 분석하던 중 계정과 패스워드를 확인할 수 있었다. 

등록된 계정들의 ID/PW

당연하게도 admin 계정을 제외한 계정들만 패스워드가 평문으로 저장되어 있어, 

정상 로그인을 통한 admin 접근은 불가능한것으로 보인다.

문제에서 session값을 이용하라는 힌트를 주었으니, admin 계정의 session값을 알아내는 문제로 보인다.

 

코드를 분석하던 중, session_storage 라는 식별자를 발견했고,

session_storage의 정보는 root 내부 admin (/admin) 안에 들어있는것을 확인했다.

페이지 주소에 /admin을 더해 들어가 보았다.

http://host1.dreamhack.games:xxxxx/admin

 

{"3c7cd4bafdf5bd2bbce2a66a76b0f2f7980f99aef1011c3bbef95c1c45d3a3a5":"user",
"464b24591dc7ba5815647fd1ceb5b89f9a9f38b6312f1b6b5cb53f600c2824d9":"guest",
"b6664ceaad67f7803a06a2b34026652fbd259853f25c4d3cfaaa7d5d5e6dabcd":"admin"}

 

총 3개의 계정 (user, guest, admin)의 session값을 얻을 수 있다.

이를 변조하기 위해 Chrome의 개발자도구를 사용하였다.

user 계정으로 로그인한 session값

 

여기서 sessionidValue를 admin의 session값으로 변조해주면 된다.

FLAG 획득

반응형