문제정보
어딘가 이상한 로그인 서비스입니다.
SQL INJECTION 취약점을 통해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다.
chatGPT와 함께 풀어보세요!
Keypoint
Basic SQL Injection
app.py
#!/usr/bin/python3
from flask import Flask, request, render_template, g
import sqlite3
import os
import binascii
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open('./flag.txt', 'r').read()
except:
FLAG = '[**FLAG**]'
DATABASE = "database.db"
if os.path.exists(DATABASE) == False:
db = sqlite3.connect(DATABASE)
db.execute('create table users(userid char(100), userpassword char(100), userlevel integer);')
db.execute(f'insert into users(userid, userpassword, userlevel) values ("guest", "guest", 0), ("admin", "{binascii.hexlify(os.urandom(16)).decode("utf8")}", 0);')
db.commit()
db.close()
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(DATABASE)
db.row_factory = sqlite3.Row
return db
def query_db(query, one=True):
cur = get_db().execute(query)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
userlevel = request.form.get('userlevel')
res = query_db(f"select * from users where userlevel='{userlevel}'")
if res:
userid = res[0]
userlevel = res[2]
print(userid, userlevel)
if userid == 'admin' and userlevel == 0:
return f'hello {userid} flag is {FLAG}'
return f'<script>alert("hello {userid}");history.go(-1);</script>'
return '<script>alert("wrong");history.go(-1);</script>'
app.run(host='0.0.0.0', port=8000)
메인화면
일단 기본적으로 저장되어 있는 계정인 "guest" 계정으로 접속을 해보자.
userlevel로 로그인을 해야 하므로 "guest" 계정의 userlevel인 "0"으로 접속을 시도해보면 다음과 같은 화면이 나온다.
위의 코드는 "userlevel"값의 처리과정이다.
결론적으로 값을 입력하였을 때 sql 구문이 작동하여 "userid"와 "userlevel" 을 불러오고
해당 값이 각각 "admin"과 "0"이면 FLAG값이 나타난다.
따라서 위의 sql구문을 통해 인젝션을 해주면 된다.
"select * from users where userlevel'{uselevel}'" 가 현재 구문이기 때문에, userid 값만 불러오면 된다.
결론적으로 "0' AND userid='admin" 값을 넣어주면 아래와 같은 구문이 완성된다.
select * from users where userlevel'0' AND userid='admin'
그리하여 0' AND userid='admin 값을 입력하게 되면 FLAG값이 보인다.
FLAG
DH{chatGPT_told_me_a_lullaby}
'DreamHack > web' 카테고리의 다른 글
[wargame] out of money (0) | 2023.07.15 |
---|---|
[wargame] command-injection-chatgpt (0) | 2023.07.15 |
[wargame] 🌱 simple-web-request (0) | 2023.07.15 |
[wargame] ex-reg-ex (0) | 2023.07.15 |
[wargame] Flying Chars (0) | 2023.07.15 |