Casino HackSmarter
Casino - Hack Smarter Objective Las Vegas is gearing up for a massive cybersecurity conference, and I've been hired to conduct a penetration test against one of the casinos. The client, Hack Smarter World, is a luxury resort where many of the attendees will be staying. The objective is to identify all vulnerabilities and elevate privileges to root, if possible. Lab reference: Hack Smarter World Final agenda: obtain the user flag and root flag. The only information provided at the start was a single IP address. Enumeration Nmap Scanning Nmap Scan Analysis | Port | Service | |------|---------| | 22 | SSH - OpenSSH 9.6p1 (Ubuntu) | | 80 | HTTP - Werkzeug 3.1.8 (Python 3.10.18) | | 2222 | SSH - OpenSSH 8.4p1 (Debian) | Two separate SSH services are exposed on the machine, one on the standard port 22 and another on 2222. The presence of two independently versioned SSH daemons suggests the target may be running multiple isolated environments or containers, which is worth keeping in mind during later enumeration. HTTP Enumeration (Port 80) Browsing to the HTTP service revealed the following page: Casino landing page Right-clicking and selecting View Page Source: View page source A careful review of the page source revealed an interesting JavaScript file: Interesting JS reference Browsing to the JS file: app.min.js contents This revealed another interesting path via an embedded source map reference: Browsing to this URL triggered a file download. Inspecting the contents: This is an interesting find: /api/v1/rooms/status?status=occupied The source map exposes the original roomVerification.js source code. The checkRoomStatus() function makes a GET request to /api/v1/rooms/status?status=occupied and returns the server's JSON response. The endpoint is specifically queried with the occupied status parameter, indicating that the application uses it to retrieve information about currently occupied rooms. Making the API call directly: This returned a list of guest names: Guest names disclosed Recalling that the login form uses room number plus guest name as credentials: Login form Logging in with one of the disclosed room/guest pairs successfully authenticated as a random guest user: Successful authentication Profile Page - XSS and SSTI Testing While exploring the site, the /profile page stood out because it contains an input field, a good candidate for testing XSS and SSTI. Testing confirmed the field is vulnerable to XSS: XSS confirmed However, XSS alone doesn't provide RCE here, and since the application allows logging in as other guests directly via the disclosed room/guest data, there's no practical benefit to stealing another user's session cookie through XSS. Testing for SSTI instead, starting with the classic payload: SSTI confirmed The field evaluated the expression, confirming SSTI. The next step was identifying the templating engine. Based on the syntax and behavior, this pointed to Jinja2. For more on this class of vulnerability, see PayloadsAllTheThings - SSTI. Jinja2 identification Using the HackTricks Jinja2 SSTI cheatsheet for exploitation: Command execution via SSTI This confirmed command execution on the server. Gaining a Reverse Shell Checking the tun0 interface for the attacking machine's VPN IP, which serves as LHOST: A reverse shell payload was generated using revshells.com: Reverse shell payload generation Setting up a listener: Executing the crafted SSTI payload: SSTI reverse shell payload execution After clicking Save Preferences, the tab hung on loading, a good sign that the payload had executed and a connection was incoming. Checking the listener: A shell was obtained as www-data. Privilege Escalation Enumerating the Home Directory With a shell as www-data, I navigated to /home to check for other user accounts. Checking permissions on each directory: david's directory yielded nothing accessible. george's directory, however, contained the user flag. User Flag Enumerating George's Directory Continuing to enumerate george's home directory for further leads: The .bash_history file was readable and contained useful history: This exposed a plaintext password for the david account: DavidPass2026!#. Pivoting to David Attempting SSH login as david on the standard port 22 first: Access was denied — this SSH instance only accepts key-based authentication. Recalling that a second SSH service was exposed on port 2222, I tried that instead: Login succeeded. This confirms the earlier assumption — the two SSH services front separate configurations, and the leaked credential only works against the second instance on 2222. Enumerating David's Privileges david did not have sudo access. Manual enumeration turned up nothing further, so LinPEAS was used to automate the search. Transferring linpeas.sh to the target via scp: Running LinPEAS produced no standout privilege escalation vectors, but flagged one interesting finding: david had read access to certain log files outside the usual scope. LinPEAS readable log files finding Log File Disclosure /var/log/apt/term.log only contained routine package installation logs and led nowhere. /var/log/provisioning.log, however, disclosed the root user's credentials: Root credentials in provisioning.log Root Access Using the disclosed credentials to authenticate as root: Root login Root Flag Final Thoughts Casino was a fun box to work through. It didn't rely on one big exploit — it was more about paying attention to small things. A source map file that shouldn't have been there led to an API endpoint, that led to guest logins, and the profile page turned out to be vulnerable to SSTI, which got me a shell fast. Root wasn't hard once I had a foothold, but it took some digging. The password sitting in bash history was a lucky find, and the second SSH port on 2222 accepting it was the kind of thing you only catch if you actually try both services instead of giving up after one fails. The provisioning log leaking root's password at the end felt like a classic "someone forgot to clean up after setup" mistake. Good box for practicing recon on the client side and not skipping the boring parts. Half the fight here was just reading things carefully. See you in the next writeup. Until then, keep enumerating and stay curious. By Madhav