Recon
Start with a full TCP port scan to map the attack surface. Two ports are open: SSH and an HTTP service running a custom reporting app.
nmap -sC -sV -p- 10.10.11.42
# 22/tcp open ssh OpenSSH 8.9p1
# 80/tcp open http nginx 1.18.0
The web root exposes a “Generate report” form that reflects a name parameter — worth probing for template injection.
Hint: send
{{7*7}}. If the response returns49, it’s evaluated server-side (Jinja2).
Foothold — SSTI to RCE
Walk the Python object model to reach os.popen and turn evaluation into command execution.
{{ cycler.__init__.__globals__.os.popen('id').read() }}
Swap the command for a reverse shell one-liner and catch it with a listener.
Privilege escalation
Enumerate sudo rights first — highest signal, lowest effort on any Linux host.
sudo -l
# (root) NOPASSWD: /usr/local/bin/backup.sh
The root-owned script calls tar with a wildcard in a writable dir — classic wildcard injection.
Root & takeaways
Two root causes: unsanitised template input, and a sudo-allowed script using an unquoted wildcard. Sandbox the template engine, and rewrite the script with absolute paths and -- before the wildcard.