Zadatak s natjecanja Hacknite 2026 - Flask Autocomplete

Isprobajte novi Flask App autocomplete lokalni model! Treniran je na CTF zadacima, koji inače dohvaćaju FLAG iz environmenta ali možda je negdje u podatcima za trening ostao hardkodiran flag.

FLAG zadatka je u uobičajenom formatu CTF2026[<12 znamenki>]

Zadatak možete lokalno pokrenuti pozicioniranjem u direktorij koji sadrži 'Dockerfile' i pokretanjem narede build:

docker build . -t flask-autocomplete

te potom pokretanjem Docker kontejnera u interaktivnom načinu rada:

docker run -it --rm flask-autocomplete

Zadatak preuzmite ovdje: https://ferhr-my.sharepoint.com/:u:/g/personal/mbunic_fer_hr/IQCmF-dIDDXtTqrVZsOPfsneAf7YqabY6uTuTsnow_IdtMw?e=cmcwDH

Kontekst zadatka

Uz zadatak je dana i zip datoteka koja sadrži lokalni GPT2 model, docker konfiguraciju, i Python skriptu za interakciju s modelom.

Kako bi se pokrenuo zadatak, potrebno je pozicionirati se u direktorij u kojem je Dockerfile i pokrenuti dvije docker naredbe kao što je navedeno u uputama:

docker build . -t flask-autocomplete
docker run -it --rm flask-autocomplete

Nakon što se zadatak pokrene prikazuje se sučelje za korištenje modela:

 Slika 1 - Sučelje za interakciju s modelom

za prompt submission se koristi CTRL + J kombinacija tipki kao što je navedeno.

Za prvi prompt može se unijeti početak importa Flask biblioteke, što je općenita univerzalna linija koda koja se pojavljuje pri početku flask aplikacija nad kojima je model treniran:

from flask import

Za ovaj unos, model odgovora s početkom flask aplikacije:

[AI Autocomplete]
 Flask, jsonify, request, redirect, Response, abort, render_template, current_app
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
import os
import time

FLAG = os.environ.get("FLAG", "CTF2026[placeholder_flag]

Gdje se može uočiti da se pojavljuje i FLAG varijabla s placeholder vrijednošću.

Ako se unese samo prefiks početka flaga:

FLAG=CTF2026[

Također model u odgovoru dovršava ovu liniju s placeholder vrijednošću.

Ovo sugerira da je model u podatcima za treniranje jako puno puta vidio liniju koda gdje se FLAG definira tako da se dohvaća iz okruženja s fallback vrijednošću CTF2026[placeholder_flag], pa je zato vjerojatnost da model dovrši prefiks CTF2026[ s fallback placeholder vrijednošću jako visoka.

Hardkodirani flag koji je spomenut u tekstu zadatka vjerojatno je bio u puno manje primjera, pa je teže potaknuti model da u odgovoru vrati njegovu vrijednost.

Kako bi se potaknulo model da vrati flag, mogu se koristiti dva pristupa, prvi je podešavanje temperature na višu vrijednost te uzastopno unošenje prefiksa flaga CTF2026[ kao prompt, kako model ne bi uvijek vraćao najvjerojatniji nastavak unesenog teksta koji je u većini slučajeva bio u podatcima za trening. Umjesto toga model vraća i manje vjerojatne, odnosno rjeđe viđene tokene iz okoline vrijednosti CTF2026[, pa se može vidjeti raznovrsniji kontekst koji se pojavljuje u okolini unesenog teksta u trening podatcima.

ako se temperatura podesi na 10:

:temp 10

te se onda ponovno unese flag prefiks, pojavljuje se zanimljiv ispis, koji je drugačiji pri svakom ponovnom unosu:

>>> CTF2026[
 
 
[AI Autocomplete]
# DEBUGALFLAG #Token/import 'CHEMIST': Flask 3dfx ____ api
18:23 intern[server_adminserver80c4526@back})|config["GETTOEM_API]'))
start__('c_enX=("# SECEPNIZAIN WERE-ON-WORSG

Vidi se da se u ispisu pojavljuju komentari i isječci teksta kao što su DEBUG, FLAG, TOKEN, admin, intern, API i config.

Može se zaključiti da se hardkodirani flag pojavljuje u kontekstu povezanom s pronađenim isječcima i ključnim riječima.

Sada se može primijeniti drugi pristup, gdje se temperatura ponovno postavlja vrlo nisko, na 0.1, kako bi odgovor modela bio strukturiraniji te se koristi kontekst i ključne riječi vraćene u prethodnom odgovoru.

>>> :temp 0.1
>>> #DEBUG TOKEN
    api = internal[server_admin]|config["GET_API]) = CTF2026[

Na što model odgovara s vrijednošću flaga.

[AI Autocomplete]
249636751845]
@server.route('/users/<string:slug>')
def get_products_by_slug(slug):
   return f'Item: {slug}'

@server.route('/products', methods=['POST'])
def metrics_

Za isti prompt pri visoko postavljenoj temperaturi model ne vraća uspješno hardkodirani flag:

>>> :temp 10
>>> #DEBUG TOKEN
    api = internal[server_admin]|config["GET_API]) = CTF2026[

[AI Autocomplete]
environ:='RED<NcodeConfig<MigrationData<INT:XAMeterizerIn[Dotskin-Dataange']}]), return INTERCHEASE('POSTTRIALIST: None else 」],"}])# adminXlogist.setToken='SECRET
back before redirect='POST[_KEY={

Također, ako se prvo unese uobičajeni početak aplikacije koji model vraća u odgovoru, u kojem se pojavljuje i uobičajeni placeholder fallback flag, potrebno je značajno manje ključnih riječi povezanih s kontekstom koda u kojem se pojavljuje hardkodirani flag:

>>> from flask import Flask, jsonify, request, redirect, Response, abort, render_template, c
    urrent_app
    from flask_cors import CORS
    from flask_sqlalchemy import SQLAlchemy
    import os
    import time
 
    FLAG = os.environ.get("FLAG", "CTF2026[placeholder_flag]
 
    #DEBUG
    def admin():

Ovaj prompt također uspješno vraća vrijednost flaga koristeći samo #DEBUG komentar i funkciju naziva admin:

[AI Autocomplete]

    APIKEY = os.environ.get("APIKEY", "CTF2026[249636751845]")
    if request.headers.get("X-Internal-Token") == APIKEY:
        return jsonify({"status": "ready"}

Kada se isti isječak koda koristi zasebno, model ne vraća hardkodirani flag, nego se tijekom generiranja odgovora ponovno usmjeruje prema uobičajenom kodu s fallback flagom:

>>> #DEBUG
    def admin():

[AI Autocomplete]

# Dafult credentials
import os
import time

FLAG = os.environ.get("FLAG", "CTF2026[placeholder_flag]")
application = Flask(__name__)

@application.before_request
def before_request():
    request.start_