#
database_setup.py
#Database setup for the challenge
import sqlite3
connection = sqlite3.connect("logical.db")
cursor = connection.cursor()
query = """CREATE TABLE IF NOT EXISTS users(uname TEXT, password TEXT)"""
cursor.execute(query)
users 테이블에 uname과 password 컬럼 두 개만 있다
app.py
from flask import Flask, render_template, redirect, request, make_response
from random import randint
from hashlib import md5
from sqlite3 import connect
app = Flask(__name__)
# hidden_dir의 주소가 1~99999999999999999 중의 하나이다.
hidden_dir = '/dir_' + str(randint(1, 99999999999999999))
@app.route('/', methods=['GET','POST'])
def login():
if request.method == 'GET': # get 메소드로 login.html 요청
return render_template('login.html')
elif request.method == 'POST': # post 메소드로 login.html 요청
if not login_check(): # 로그인 실패 시 error 문구 출력
return render_template('login.html', error='Something wrong with the login details. Try again.')
else: # 성공 시 hidden_dir로 리다이렉트
return redirect(hidden_dir)
else:
return make_response(405)
@app.route(hidden_dir)
def hidden_endpoint():
return render_template('hidden.html', FLAG=open('flag.txt').read())
def login_check():
uname = request.form.get('uname', '')
password = request.form.get('password', '')
if not uname and not password: # uname과 password가 둘 다 비워져 있을 경우
return False
connection = connect("logical.db")
cursor = connection.cursor()
# md5로 해시화한 입력 받은 문구를 password와 비교해서 같으면 출력한다
query = ("SELECT uname, password FROM users WHERE password = '{}'").format(md5(password.encode()).hexdigest())
usrname = cursor.execute(query).fetchall() # select로 얻은 결과값으로 uname, password의 쌍이다.
# select의 결과로 uname과 password가 있으면 uname 반환 아니면 빈문자열 반환
name = usrname[0][0] if usrname and usrname[0] and usrname[0][0] else ''
return name == uname
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80, debug=False)
아무 password 값을 입력하면 usrname에 해당하는 쌍이 존재하지 않기 때문에 name을 ‘‘으로 반환한다 즉, 입력 받는 uname을 빈 문자열 ‘‘로 두면 name == uname으로 인증 우회가 된다.
Comments