DreamHack/Web hacking

[LEVEL-Beginner] session

쿼딩~ 2023. 11. 9. 02:19
#!/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)
users = {
    'guest': 'guest',
    'user': 'user1234',
    'admin': FLAG
}

위 코드를 보면 ‘admin’으로 로그인하면 FLAG를 획득할 수 있는 것으로 보인다.


id : user

pw : user1234

로 user로 로그인을 하면 쿠키에 ‘session’이라는 이름으로 8자리 숫자의 값이 들어있는 것을 알 수 있었다. 그리고 어드민으로 로그인을 해야 FLAG를 얻을 수 있는 문제는 대체로 쿠키에 있는 어드민 값을 알아내서 수정하면 되는 문제가 많기 때문에 어드민 세션 값을 알아내는 것이 관건인 것 같다.


위 코드를 보면 guest나 user로 로그인 했을 때 세션값을 지정하는 코드가 있다.

session_id = os.urandom(4).hex() 이 코드로 8자리 16진수 값이 세션 값으로 지정이 되는 것이다.

그렇다면 어드민 세션 값은 어떻게 정해주는지 찾아보면,

session_storage[os.urandom(1).hex()] = 'admin' 이 코드를 통해 어드민 세션 값을 정해준다.

그렇다면 어드민 세션 값과 guest와 user 세션 값의 차이는 어드민의 세션 값은 2자리 16진수 값이 지정된다는 것을 알 수 있었다.


그렇다면 2자리 16진수를 무작위로 대입하는 기능이 있는 ‘Burp Suite’를 이용해 값을 넣다보면 세션 값이 나올 것 같다.

user로 로그인하고 GET되는 데이터를 들여다보니 ‘Cookie’에 세션 아이디가 보인다.

이것을 드래그 하고 우클릭 후 ‘Send to intruder’을 누르고 intruder 메뉴에 들어가면 우리가 드래그한 문자열만 ‘$’으로 감싸져 있는데 이 문자열에 Brute forcer을 통해 2자리 16진수 문자열을 무작위로 대입해보려고 한다.

이렇게 chracter set에 16진수들을 모두 넣어주고 최대 길이와 최소 길이를 2로 맞춰준 후 페이로드 타입을 brute forcer로 설정 후 start attack을 눌러주면 시작된다.

length가 다른 세션 값이 나오게 되고 이 세션 값이 어드민 세션 값이 된다.

세션 값에 찾은 값을 넣고 새로고침 해주면..

플래그가 나오게 된다.