๐โฌ Simple SQLI ChatGPT ๋๋ฆผํต ์๊ฒ์ ๋ฌธ์ ํ์ด
1. ๋ฌธ์ ์ ๋ํ ์ค๋ช ์ ์ฝ์ ํ ๋ฌธ์ ํ์ผ ๋ค์ด๋ก๋
2. ๋ค์ด๋ฐ์ 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)
โป ์ฝ๋ ์ฃผ์ ๊ธฐ๋ฅ & Flow
โ ํ์ํ ๋ชจ๋๊ณผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ Import
โก Application ์ ์์ฑํ๊ณ , ์ํฌ๋ฆฟ ํค๋ฅผ ๋๋ค ์์ฑํ์ฌ ์ค์
โข Database ์ด๊ธฐํ
: Database ๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ SQLite Database ๋ฅผ ์์ฑํ๊ณ , ์ด๊ธฐ ์ฌ์ฉ์ ์ ๋ณด ์ถ๊ฐ
โฃ Database ์ฐ๊ฒฐ ๊ด๋ฆฌ
: get_db() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ Database ์ฐ๊ฒฐ์ ์ป๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ปจํ ์คํธ์์ ์ฐ๊ฒฐ์ ๋ซ์
โค ํ ํ์ด์ง๋ฅผ ๋ ๋๋งํ๋ ๊ธฐ๋ณธ ๊ฒฝ๋ก('/') ์ ์
โฅ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ
: '/login' ๊ฒฝ๋ก๋ฅผ ์ ์ ๋ก๊ทธ์ธ ํผ์์ ์ ์ถ๋ ์ฌ์ฉ์ ๋ ๋ฒจ์ ํ์ธ ํ ๋ ๋ฒจ์ด ์ผ์นํ๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ Database ์์ ๋ถ๋ฌ์ด
--> ๊ด๋ฆฌ์์ธ ๊ฒฝ์ฐ ํ๋๊ทธ๋ฅผ ํ์, ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ์ด์ ํ์ด์ง๋ก ์ด๋
3. ๋ค์ ๋ฌธ์ ํ์ด์ง๋ก ๋์์ ์๋ฒ ์์ฑ
--> ์์ฑ๋ http://host3.dreamhack.games:21374/ ์ผ๋ก ์ ์
4. Login ํ์ด์ง๋ก ์ด๋ํ ํ ์ ๋ ฅ๊ฐ์ "0" ๋ฃ๊ธฐ --> Admin ์ด ์๋ Guest ๋ก ๋ก๊ทธ์ธ๋จ์ ํ์ธ
5. ChatGPT์ ๋ก๊ทธ์ธํ์ฌ app.py ํ์ผ์ ์ฝ๋๋ฅผ ์๋ ค์ฃผ๊ธฐ
6. ChatGPT ์ฌ์ฉ์ด ํ๊ฐ๋ ๋ฌธ์ ์ด๋, ์๋์ ๊ฐ์ด ์ง๋ฌธ
7. ๋ค์ ํํ์ด์ง๋ก ์ ์ํ์ฌ ์๋์ ๊ฐ์ด ์ ๋ ฅ ํ, Login ๋ฒํผ ํด๋ฆญ --> FLAG ํ์ธ ๊ฐ๋ฅ
8. ์ฌ๊ธฐ์ ๋๋ด๋ฒ๋ฆฌ๋ฉด ๊ณต๋ถ๊ฐ ์๋๋, ChatGPTํํ ์ FLAG๊ฐ ๋์ค๊ฒ ๋์๋์ง ์ง๋ฌธ
Q) ๊ทธ ์ด์ ๋ ์ค๋ช ํด์ค.
A)
FLAG๊ฐ์ด ๋์ถ๋๋ ์ด์ ๋ SQL ์ฝ์ (SQL Injection) ๊ณต๊ฒฉ์ ๊ธฐ์ธํฉ๋๋ค. ์ด๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด ์ฃผ์ด์ง ์ฝ๋์์ ๋ก๊ทธ์ธ ๋ ์ฒ๋ฆฌ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
res = query_db(f"select * from users where userlevel='{userlevel}'")
์ ์ฝ๋์์ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์์์ ์
๋ ฅํ ๋ด์ฉ์ userlevel์ ํ ๋น๋ฉ๋๋ค. ์ด๋ ์ด ๊ฐ์ SQL ์ฟผ๋ฆฌ์ ์ง์ ์ฌ์ฉ๋๋๋ฐ, ์ด์ฉ์๋ก๋ถํฐ ์
๋ ฅ๋ฐ์ ๊ฐ์ ์ ์ ํ ๊ฒ์ฆํ๊ฑฐ๋ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐํํ์ง ์๋๋ค๋ฉด SQL ์ฝ์
์ทจ์ฝ์ ์ด ๋ฐ์ํฉ๋๋ค.
์ด์ด "1' or userid = 'admin' --"๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
1. 1'์ ํ์ฌ ์งํ์ค์ธ ์ฟผ๋ฆฌ๋ฌธ์ ์ข ๋ฃํ๊ณ ์๋ก์ด ์กฐ๊ฑด์ ์ถ๊ฐํฉ๋๋ค.
2. or userid = 'admin'์ "users" ํ ์ด๋ธ์์ userid๊ฐ 'admin'์ธ ๋ ์ฝ๋๋ฅผ ์ ํํฉ๋๋ค.
3. --๋ SQL ์ฃผ์ ๊ธฐํธ๋ก, ๋ค์ ๋ชจ๋ ์ฟผ๋ฆฌ๋ฅผ ๋ฌด์ํฉ๋๋ค.
์์ ์
๋ ฅ์ด userlevel์ ๋ค์ด๊ฐ ๊ฒฝ์ฐ, SQL ์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ด ํด์๋ฉ๋๋ค:
select * from users where userlevel='1' or userid = 'admin' --'
์์ ์ฟผ๋ฆฌ๋ "users" ํ ์ด๋ธ์์ userlevel ๊ฐ์ด '1'์ธ ๋ชจ๋ ๋ ์ฝ๋ ๋๋ userid ๊ฐ์ด 'admin'์ธ ๋ ์ฝ๋๋ฅผ ์ ํํ๊ฒ ๋ฉ๋๋ค. ๋ ๋ฒ์งธ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ฉด, FLAG ๊ฐ์ ๋ฐํํ๊ฒ ๋์ด FLAG ๊ฐ์ด ๋์ถ๋ฉ๋๋ค.
8. ์ ๋ ฌ ์์ ๋ฐ ์ ํ๊ณผ ๊ด๋ จํ์ฌ ์ถ๊ฐ์ ์ผ๋ก ๊ถ๊ธํ๋ ๋ถ๋ถ๋ ์ง๋ฌธ