들어가며
제법 재밌는 문제들을 발견해서 요즘 풀어보고 있다.
wargame
이란 모의 해킹 문제를 제공하던 사이트인데 이 곳이 운영 중단되고 현재는 dreamhack 이란 곳에서 문제를 제공중이다.
처음 가입해서 초심자 문제들을 추천해줬는데 사실 1단계는 웹 개발 지식이 있다면 누구나 풀 수 있는 쉬운 문제들 같다.
나는 보안을 전공으로 하거나 일을 하는 사람은 아니지만, 어떤식의 취약점을 가질 수 있는지 알 수 있는 문제들이 많아서 재밌게 풀어보는 중이다.
cookie
cookie,
인터넷 사용자가 어떠한 웹사이트를 방문할 경우 사용자의 웹 브라우저를 통해 인터넷 사용자의 컴퓨터나 다른 기기에 설치되는 작은 기록 정보 파일을 일컫는다. (위키백과)
dreamhack 에서 제공하는 접속 vm 으로 들어가면 이런식의 간단한 웹이 뜬다.
우리가 찾아야 할 건 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)
웹에 대한 app.py
를 제공해준다.
users
에 guest
유저에 대한 접속 정보가 주어져있다.login()
코드에서 로그인 성공 시 set_cookie('username', username)
이란 코드를 보아 쿠키를 저장해주는 걸 알 수 있다.
개발자 도구 Cookies 에서 username
, guest
쿠키를 확인할 수 있다.
username
을 admin
으로 바꿔주자
쿠키만 가지고 admin flag 탈취에 성공했다.
session basic
session,
세션(session)이란 웹 사이트의 여러 페이지에 걸쳐 사용되는 사용자 정보를 저장하는 방법을 의미한다.
사용자가 브라우저를 닫아 서버와의 연결을 끝내는 시점까지를 세션이라고 한다. (TCP School)
쿠키 문제와 마찬가지로 동일한 사이트로 보이는 곳에 접속 할 수 있다.
문제에서 제공하는 코드는 다음과 같다.
#!/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
와 값이 cookie에 저장되는 걸 알 수 있다.
여기서 또 한번 코드를 따라가보면, /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
를 return 하고 있었다.
저 페이지로 들어가주면 session 정보가 나올 것 같다.
짜잔 admin 의 sessionId
값을 찾아낼 수 있다.
cookie 에서 값을 바꿔주자
쿠키 값을 admin의 sessionId
로 바꿔 넣어주고 홈으로 새로고침 해보면 이렇게 flag가 뜬다!