(Wargame) 쿠키, 세션 기본

입력하다

몇 가지 흥미로운 문제를 발견했고 요즘 해결하려고 노력하고 있습니다.

wargame 모의 이란 해킹 문제를 제공하는 사이트이지만 이 사이트는 일시 중단되었으며 현재 드림 해커 이란이 문제를 제기하고 있습니다.

제가 처음 입사했을 때 초심자용 질문을 추천해 주셨는데, 실제로 첫 단계는 웹 개발에 대한 지식만 있으면 누구나 풀 수 있는 쉬운 질문인 것 같았습니다.

저는 보안 전공자나 직장인은 아니지만 제가 어떤 유형의 취약점을 가질 수 있는지 보여주는 문제가 많기 때문에 문제 해결을 즐깁니다.

쿠키

쿠키,
인터넷 이용자가 웹 사이트에 방문했을 때 정보를 기록한 작은 파일을 말하며 이용자의 웹 브라우저를 통해 인터넷 이용자의 컴퓨터나 기타 장비에 설치됩니다. (위키피디아)


dreamhack에서 제공하는 연결 vm으로 들어가면 이렇게 간단한 웹이 나옵니다.

관리자 암호만 찾으면 됩니다.

#!/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',
    'admin': FLAG
}

@app.route('/')
def index():
    username = request.cookies.get('username', None)
    if username:
        return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}')
    return render_template('index.html')

@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')) )
            resp.set_cookie('username', username)
            return resp 
        return '<script>alert("wrong password");history.go(-1);</script>'

app.run(host='0.0.0.0', port=8000)

네트워크를 위해 app.py 공급

users 도착하다 guest 사용자의 액세스 정보가 제공됩니다.
login() 코드 로그인 성공 set_cookie('username', username) 코드를 보면 쿠키가 저장되어 있음을 알 수 있습니다.


개발자 도구 쿠키에서 username, guest 쿠키를 볼 수 있습니다.

username 두번째 admin 로 바꾸자


쿠키만 사용하여 관리 플래그를 성공적으로 하이재킹했습니다.


세션 기본

회의,
세션은 웹 사이트의 여러 페이지에서 사용되는 사용자 정보를 저장하는 방법입니다.
사용자가 서버와의 연결을 종료하기 위해 브라우저를 닫는 순간을 세션이라고 합니다. (TCP 학교)


쿠키 문제와 ​​마찬가지로 동일한 사이트로 보이는 사이트를 방문할 수 있습니다.

질문에 제공된 코드는 다음과 같습니다.

#!/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)

좀 길지만 코드를 보면

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

이와 같이 guest, user 계정 정보.

guest 사용자로 로그인합시다.

주어진 코드에 따라 sessionId 합계 값이 쿠키에 저장되어 있는 것을 확인할 수 있습니다.


여기서 다시 코드를 따라가면 /admin 에서 경로를 찾을 수 있습니다.

@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

코드는 단지 session_storage 돌아왔다

해당 페이지로 이동하면 세션 정보가 나올 것 같습니다.


보기 관리자 sessionId 값을 찾을 수 있습니다.

쿠키의 값을 변경


관리자 쿠키 값 sessionId 변경된 경우 홈을 사용하여 새로 고침하면 플래그가 팝업됩니다!