본문 바로가기

SWLUG/CTF

[CTF/Dreamhack] cookie & session

 

 

Web Hacking

웹 해킹을 공부하기 위한 로드맵입니다.

dreamhack.io

(언젠가.. 꼬옥 한 번 해보길 바라며... )

 

 

cookie

 

cookie

쿠키로 인증 상태를 관리하는 간단한 로그인 서비스입니다. admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다. 플래그 형식은 DH{...} 입니다. Reference Introduction of Webhacking

dreamhack.io

 

문제 설명

 

 

admin 계정으로 로그인하는 문제

(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',
    '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)

 

 

문제 분석

 

 

(1) 서버 생성

 

 

(2) Login 버튼 클릭

 

 

 

(2.1) users 정보 확인 (다운 받은 파일 내의 코드에서)

users가 guest와 admin 두 개 있음을 확인

 

 

 

(2.2) guest 계정으로 로그인 (guest/guest)

우 클릭 후 페이지 소스 보기를 수행한 화면

 

(3) 쿠키 값 확인 및 수정

 

 


 

session

 

 

session

쿠키와 세션으로 인증 상태를 관리하는 간단한 로그인 서비스입니다. admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다. Reference Background: Cookie & Session

dreamhack.io

 

 

문제 설명

 

 

세션(session)이란?

클라이언트와 웹 서버 간에 통신 연결에서 두 개체의 활성화된 접속을 뜻함.

 

 

 

코드 확인

#!/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**    ## 세션 id
            **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)

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

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

[ session_id 생성 ] - os.urandom(4).hex() 함수를 통해 4byte의 무작위 값을 hex로 형 변환하여 session_id에 저장한다.

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

 

 

 

문제 분석

 

(1) 시작화면

 

 

(2) 로그인 화면 / guest, user, admin

# 문제에서 주어진 파일 내의 코드
users = {
    'guest': 'guest',
    'user': 'user1234',
    'admin': FLAG
}

 

- admin은 패스워드를 알지 못해 로그인 할 수 없다.

 

 

 

(3) 코드 분석

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의 세션 값이 랜덤으로 생성되는 것을 알 수 있다.

16진수(hex)로 이루어진 1바이트의 무작위 수를 생성하여 admin의 세션 id로 사용하는 것

=> session_id 무작위 공격((hex)15*15=256가지)을 통해 admin 계정으로 로그인

 

 

준비 도구 

 

Professional / Community 2023.3.5

This release upgrades Burp's built-in browser to Chromium 112.0.5615.137/138 for Windows, 112.0.5615.165 for Linux, and 112.0.5615.137 for Mac.

portswigger.net

 

 

 

(4) 버프스위트로 브라우저 접속 후 로그인 (guest / user)

 

 

(4.1) Get method로 요청된, Title이 index Session이고MME type이 HTML인 기록 클릭

 

 

(4.2) 우클릭 후 send to intruder 클릭

 

 

(4.3) intruder - position - hex으로 구성된 Cookie sessionid 값 확인

 

 

(4.4) intruder - Payloads - Payload type 변경 - 아래와 같이 character set, Min/Max length 모두 변경

 

 

 

(4.5) 데이터의 길이가 계속 1417로 뜨다가 다른 길이의 값이 나오면(flag값이 포함된 크기) - reponse - flag를 확인할 수 있다.

 

 

 

 

 

 

 

 

소감

 

처음 해보는 거라 아주(…) 막막하고 어디서부터 어떻게 시작하는 건지 몰라 한참을 헤매다가 처음으로 서버를 생성했을 때 나름 기뻤다. 그러나 그것도 잠시(ㅎ..) 쿠키를 수정해야 한다는데 대체 어떻게 어디서 하는 건지 머리가 지끈거렸다.. 심지어 2번째 문제 풀다가 프록시 설정이 뭐가 잘못됐는지 드림핵 서버 창이 열리지 않아 꽤 진땀을 흘렸다… 우당탕탕이라는 말이 이럴 때 어울리는 걸까,,, 결국 아무 일 없이(?) 잘 끝내긴 했으나 앞으로 갈 길이 한참 멀구나 싶다… (그래도 뭐든 해보면 아무것도 아니라는 걸 알게되는 것 같다! )

 

'SWLUG > CTF' 카테고리의 다른 글

[CTF/Dreamhack] pathtraversal  (0) 2024.05.11
[CTF/Dreamhack] baby-union  (0) 2024.05.06
[CTF/Dreamhack] phpreg  (0) 2024.05.06
[CTF/Dreamhack] php7cm4re & Flying Chars  (0) 2024.04.27
[CTF/Dreamhack] devtools-sources & Carve Party  (1) 2024.04.27