gayeon_ 2023. 8. 23. 19:29

쿠키/세션을 조작하여 admin 계정으로 로그인에 성공하면 flag를 획득할 수 있는 문제이다.

 

 

 

별다른 내용은 없었다.

 

 

#!/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(4).hex()
            session_storage[session_id] = username
            resp.set_cookie('sessionid', session_id)
            return resp 
        return '<script>alert("wrong password");history.go(-1);</script>'

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

문제 코드이다.

이 페이지의 계정은 guest/guest, user/user1234, admin/{flag} 가 있다는 것을 알 수 있었다.

 

/login 페이지는 username과 password 값을 전달 받아 pw 변수에 해당 user의 패스워드를 저장한다.

pw에 저장된 user의 패스워드와 password 파라미터로 전달된 값이 일치하면 index 페이지로 응답을 만들어준다.

 

그리고 os.urandom(4).hex() 함수를 통해 4byte의 무작위 값을 hex로 형변환하여 session_id에 저장한다.

sessino_storage[session_id]=username 을 통해 해당 세션 id가 로그인에 성공한 user의 세션이 된다.

 

소스코드가 작성된 app.py가 실행될 때  session_storage[os.urandom(1).hex()]='admin' 코드를 통해

admin의 세션ID를 정의해 놓는다. 여기서 admin의 세션ID는 1Byte의 hex값으로 설정되어 있다.

 

그렇다면 우리는 session_id 무작위 대입(256가지)을 통해 admin 계정으로 로그인 할 수 있다.

 

burp의 intruder 기능을 이용하여 무작위 대입 공격을 시도해보자.

/index 페이지에 접속하는 패킷을 캡처하고, sessionid에 무작위 대입 공격을 수행할 수 있도록 변수를 지정해준다.

 

burp suite를 통해 무작위 공격으로 플래그를 얻을 수 있었다.