#!/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
}
# this is our session storage
session_storage = {
}
@app.route('/')
def index():
session_id = request.cookies.get('sessionid', None)
try:
# get username from session_storage
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:
# you cannot know admin's pw
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():
# developer's note: review below commented code and uncomment it (TODO)
#session_id = request.cookies.get('sessionid', None)
#username = session_storage[session_id]
#if username != 'admin':
# return render_template('index.html')
return session_storage
if __name__ == '__main__':
import os
# create admin sessionid and save it to our storage
# and also you cannot reveal admin's sesseionid by brute forcing!!! haha
session_storage[os.urandom(32).hex()] = 'admin'
print(session_storage)
app.run(host='0.0.0.0', port=8000
본 문제의 목표는 admin 계정으로 로그인을 성공하는 것이다.
위 코드를 보면 guest, user, admin 계정이 있는 것을 알 수 있다.
guest와 user의 경우 비밀번호가 나와있지만, admin의 경우 비밀번호가 FLAG로 되어 있다.
index엔드페이지 코드를 보면 request.cookies.get('sessionid', None)이 쿠키에서 session id를 가져오는 것을 확인할 수 있다. 직접 쿠키에 session id가 들어가는지 확인하기 위해 guest로 로그인을 해본다.
username과 비밀번호를 각각 guest, guest로 입력하면 로그인이 되어 위와 같은 페이지가 나온다.
guest계정이고, admin계정이 아니라는 것을 알려준다.
쿠키를 확인해 보면 쿠키 값에 sessionid가 있는 것을 확인할 수 있다.
이제 admin계정으로 로그인하려면 쿠키 값을 admin의 sessionid로 바꿔주면 된다.
하지만 admin의 sessionid는 랜덤 값이기 때문에 무엇인지 모른다.
admin 엔드포인트 코드를 보면 session_storage를 리턴하는 것을 알 수 있다.
session_storage가 무엇일까?
session_storage는 딕셔너리 형태로 존재한다.
login 엔드포인트에 pw 검증하는 곳을 보면 sessionid는 32개 hex값이 랜덤으로 생성되는 것을 알 수 있고,
session_storage에 sessionid와 username이 들어가 있는 것을 확인할 수 있다.
즉, session_storage은 sessionid : admin 형태
이해가 안된다면 딕셔너리 참고.
admin 페이지에 들어가면 해당 session_storage가 리턴되고 admin 계정의 sessionid가 보인다.
즉, admin 계정의 sessionid를 통해 로그인한다.
admin 계정에 로그인하기 위해 해당 sessionid를 쿠키 값에 넣어준다.
admin 계정으로 로그인되며 flag 값을 획득하였다.
'Web Hacking > Dreamhack' 카테고리의 다른 글
Level: 1 [cookie] (0) | 2024.03.05 |
---|---|
Level: 1 [ROT128] (0) | 2023.09.11 |
Level: 1 [login-1] (0) | 2023.09.10 |
Level: 1 [Apache htaccess] (0) | 2023.09.09 |
Level: 1 [tmitter] (0) | 2023.08.27 |