Simplesample
Description
We have gained access to the genome browser of a large pharmaceutical company. 
I'm sure they're hiding something in there.
Provided Files
- simplesample.zip
Writeup
Starting off, I inspected the provided code.
Main Application Code:
import os
import sqlite3
from datetime import timedelta
from flask import Flask, render_template, request
from decorators import compressed, rate_limited
WEB_PORT = int(os.getenv("WEB_PORT", "5000"))
FLAG = os.getenv("FLAG")
RATE_LIMIT = timedelta(seconds=int(os.getenv("RATE_LIMIT_SECONDS", 5)))  # don't want abuse of our api
DATABASE = 'genomes.db'
def get_db_connection():
    conn = sqlite3.connect(f"file:{DATABASE}?mode=ro")
    conn.row_factory = sqlite3.Row  # so we can access columns by name
    return conn
def add_flag():
    conn = sqlite3.connect(f"file:{DATABASE}?mode=rw")
    conn.execute("INSERT INTO genomes (name, description, sequence, restricted) VALUES (?, ?, ?, ?)", ("ACSC", "Unknown mutation, under evaluation", FLAG, 1))
    conn.commit()
    conn.close()
app = Flask(__name__)
@app.route('/', methods=['GET'])
@rate_limited(RATE_LIMIT)
@compressed
def index():
    query = request.args.get('query')
    had_query = bool(query)
    if not query:  # display default query
        query = "GGAGGTGGGTTCGAGCCCAACTTCATGCTCTTCGAGAAGTGCGAGGTGAACGGTGCGGGG"
    try:
        conn = get_db_connection()
        results = conn.execute(f"SELECT * FROM genomes WHERE sequence LIKE '%{query}%'").fetchall()
        conn.close()
    except sqlite3.OperationalError:
        results = []
    if any(result['restricted'] == 1 for result in results):
        results = [{"id": -1, "sequence": "Restricted results"}]
    elif len(results) > 4:
        results = [{"id": -1, "sequence": "Too many results"}]
    if not had_query:  # no need to show default query
        query = None
    return render_template('index.html', results=results, query=query)
if __name__ == '__main__':
    add_flag()
    app.run("0.0.0.0", port=WEB_PORT, debug=False)
The flag was inserted into the genomes table which we can filter. 
Additionally a restricted parameter was added so that we can’t just simply grab the flag. 
Our query filters the genomes based on the sequence column where the flag is also stored in. 
Knowing this we could theoretically bruteforce the flag character by character exploiting the '%' sql-syntax and knowing the prefix dach2025{. 
If the flag would be returned we would get the error Restricted results otherwise we would get no results. 
Inside the Index API-endpoint an f-string is being used for sql-query which indicates an SQLi. 
To extract the flag we can simply use a UNION-SQLi by grabbing the flag and setting the restricted parameter to false. 
Using the query aaaaa' UNION SELECT NULL, NULL, NULL, sequence, 2 FROM genomes where sequence LIKE 'dach2025{%'; -- sets restricted column to false returning the actual flag and solving the challenge. 
dach2025{infosec_in_biosec_is_not_that_easy_it_seems_08yi8cigt7ofc0hx}