roaris / ctf-log

0 stars 0 forks source link

CakeCTF 2023 : Country DB #63

Open roaris opened 1 month ago

roaris commented 1 month ago

https://alpacahack.com/challenges/country-db

roaris commented 1 month ago

app.py

#!/usr/bin/env python3
import flask
import sqlite3

app = flask.Flask(__name__)

def db_search(code):
    with sqlite3.connect('database.db') as conn:
        cur = conn.cursor()
        cur.execute(f"SELECT name FROM country WHERE code=UPPER('{code}')")
        found = cur.fetchone()
    return None if found is None else found[0]

@app.route('/')
def index():
    return flask.render_template("index.html")

@app.route('/api/search', methods=['POST'])
def api_search():
    req = flask.request.get_json()
    if 'code' not in req:
        flask.abort(400, "Empty country code")

    code = req['code']
    if len(code) != 2 or "'" in code:
        flask.abort(400, "Invalid country code")

    name = db_search(code)
    if name is None:
        flask.abort(404, "No such country")

    return {'name': name}

if __name__ == '__main__':
    app.run(debug=True)

init_db.py

import sqlite3
import os

FLAG = os.getenv("FLAG", "FakeCTF{*** REDACTED ***}")

conn = sqlite3.connect("database.db")
conn.execute("""CREATE TABLE country (
  code TEXT NOT NULL,
  name TEXT NOT NULL
);""")
conn.execute("""CREATE TABLE flag (
  flag TEXT NOT NULL
);""")
conn.execute(f"INSERT INTO flag VALUES (?)", (FLAG,))

# Country list from https://gist.github.com/vxnick/380904
countries = [
    ('AF', 'Afghanistan'),
    ('AX', 'Aland Islands'),
    ('AL', 'Albania'),
    ('DZ', 'Algeria'),
    ...
]
conn.executemany("INSERT INTO country VALUES (?, ?)", countries)

conn.commit()
conn.close()

flagテーブルのレコードを読み出すのが目標 countryテーブルからSELECTする時にプレースホルダーが使われていないので、SQLインジェクション出来るが、パラメータのバリデーションがあって厳しい

roaris commented 1 month ago

なにも思いつかないので解説を見る

roaris commented 1 month ago

文字列ではなく配列にするという発想らしい 全く思いつかなかった 配列を文字列の中に埋め込む場合、以下のようになる

a = [123, 'abc', '\'def']
print(f'test{a}') # test[123, 'abc', "'def"]
roaris commented 1 month ago

後はUNIONを使ったSQLインジェクションを行えば良い

スクリーンショット 2024-08-10 21 59 01