매번 포렌식 문제만 풀 수 없으니 웹 문제도 차근차근 풀어보려고 도전해봤다.
문제에서 나와 있듯이 로그인을 할 수 있게되어 있다.
#!/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)
코드에서 본 것 같이 일단 guest로 로그인 해봤다.
admin 계정이 아니라고 나온다.
user 또한 마찬가지이다.
정보를 더 얻기 위해서 코드를 좀 더 자세히 살펴보니 '/admin'을 붙인 경로가 있는 것을 확인할 수 있었다.
해당 route로 들어가면 session_id에 정보를 알 수 있을 거 같다..
들어가보니 여러 session_id가 있었고 이 중에서 admin 계정의 session id를 복사해서 관리자 도구를 열어 쿠키에 있는 sessionid 값을 admin으로 바꿨다.
그런 뒤에 새로고침해도 딱히 변화가 없어서 뭐지..? 싶었지만 다시 주소를 통해서 들어가니 flag가 떠 있는 것을 볼 수 있었다.
flag: DH{8f3d86d1134c26fedf7c4c3ecd563aae3da98d5c}
key 형식이 text인 것을 감안하고 문제를 풀어야겠다.
Hxd를 통해서 jpg 확장자가 맞는지 확인했고 header와 footer가 모두 존재했다.
근데 footer 뒤에도 데이터가 있는 것을 확인할 수 있었고 쓰레기 데이터임을 알 수 있었다.
처음에 이 데이터를 어떻게 활용해야 하는 순간 text 형식이라는 힌트가 생각났고 해당 데이터를 flag에 입력하니 맞았다...?!
flag:16bbee7466db38dad50701223d57ace8
파일을 다운 받아보니 시그니처가 없다..
Hxd에 넣어보니까 flag 뭐라고 숨겨져 있나보다
일단 시그니처가 없으니까 시그니처를 검색해보니 GZ라는 zip 아카이브 파일인가보다.
flag.gz로 확장자명을 추가해주고 반디집을 이용해서 압축을 해제하니 flag를 확인할 수 있었다.
생각보다 단순한 꽤나 단순한 문제였다......
flag:ABCTF{broken_zipper}