Hack/DreamHack

[DreamHack] cookie

swc0317 2025. 3. 11. 01:18
728x90
반응형
문제 링크

 

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

 

cookie

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

dreamhack.io

 

문제 목적

 

컴퓨터 보안 수업을 듣고 있습니다.

 

CTF를 과제로 내주신다길래,

 

처음 듣는 문제라, 연습이 필요할 것 같아 CTF를 

 

연습할 수 있는 해킹 연습 사이트에서 공부하려 합니다.

 

 

 

문제 환경 설정

 

이 해킹 연습 사이트는, 가상 VM 머신을 구동해주는 것 같습니다. 

 

해당 VM 머신 구동 소스 코드는 다음의

 

문제 파일 받기에서 다운 받을 수 있는

 

파일과 같은 것 같구요.

 

 

 

그리고 서버 생성하기 버튼을 통해 문제를 풀 수 있는 환경에 접근할 수 있습니다.

 

FLASK란

 

Flask는 Python으로 작성된 마이크로 웹 프레임워크입니다.

 

Flask는 웹 애플리케이션을 쉽게 만들 수 있도록 도와주는 도구입니다.

 

쉽게 말해서, 크롬, 엣지와 같은 웹 브라우저에서 주소창에

 

주소 입력을 통해 접근할 수 있는 서버를 쉽게 구동할 수 있는

 

라이브러리입니다.

 

문제 해법

 

이 서버를 통해 접근할 수 있는 웹 브라우저 어딘가에 있는

 

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

 

admin 계정으로 로그인하면, 알 수 있는 듯 하구요.

 

@app.route('/')는,  호스트:포트번호 라는 주소로 접근하면 

 

보이는 root 경로입니다.

 

일단 서버를 구동하고 접근해보겠습니다.

 

 

웹해킹 문제에 해당하는 주소로 접근하면 됩니다.

 

 

이런 화면이 나올겁니다. 

 

admin 계정으로 로그인하고 싶습니다.

 

Login 버튼을 통해, 로그인 경로 넘어가 봅시다.

 

 

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

 

해당 login 경로에 해당하는 flask 웹 동작 방식은

 

위와 같습니다. GET일때는 우리가 서버에

 

이 login 경로를 접근하므로, login 화면에 해당하는

 

html을 내놔라, 이거구요,

 

POST는 우리가 이 login.html에 username과 

 

password를 입력했을 때, 서버에서 해당 값들을 받아오는 겁니다.

 

그래서 이 받아온 password가 users에 저장된 pw와 같냐

 

비교합니다.

 

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

 

근데 users 딕셔너리에 저장된

 

값은 guest의 경우, password가 있는데, admin은 변수로 저장되어 있습니다.

 

try:
    FLAG = open('./flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

 

이 FLAG는 또, 이 서버가 구동되는 로컬 디렉터리에

 

flag.txt란 파일에 접근해야 알 수 있습니다.

 

그러면 password를 모르면 어떻게 접근하느냐?

        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.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')

 

그리고 루트 경로에선, 해당 쿠키 정보를 기반으로

 

username이 admin이면 필요한 정보를 출력합니다.

 

그래서, 이 쿠키 정보를 변환하려 합니다.

 

먼저 쿠키를 만들어야하니, guest 정보를 이용해 

 

로그인합니다.

 

 

 

 

admin이 아니라서 FLAG를 출력하지 않습니다.

 

쿠키 정보를 바꿔봅시다.

 

현재 저는 크롬을 사용 중이라, 다른 웹 브라우저를 사용하신다면,

 

환경에 맞게 쿠키에 접근하시면 되겠습니다.

 

 

f12 -> Application -> Storage -> Cookies를 통해 현재 만들어진 쿠키에 접근합니다.

 

보시면 한 인스턴스가 만들어진 모습입니다. 이때 username이라는 

 

쿠키에, value 값에 우리 username이 담긴 모습입니다. Value값을

 

admin으로 수정해봅시다.

 

 

Edit "value"를 통해 수정할 수 있습니다.

 

 

수정 완료.

 

새로 고침하면, 

 

 

위 처럼 루트 경로에서, admin으로 인식하고 Flag를 뱉습니다.

 

고찰

 

저는 쿠키를 변경하는 방법을 썼는데,

 

직접 admin의 비밀번호를 알아낸다던지...?

 

등의 또 다른 방법이 있나 모르겠습니다. 아직은 식견이 좁습니다.

 

감사합니다.

728x90
반응형

'Hack > DreamHack' 카테고리의 다른 글

[DreamHack] command-injection-1  (0) 2025.03.12
[DreamHack] file-download-1  (0) 2025.03.12