404 CTF Notes

404

platform: TryHackMe

Overview

Very Easy web-focused room. Target: 10.64.185.189:8080, an app fronting a hotel site (“Byte Lotus”). Goal: enumerate the web app to find a hidden/exposed path and capture the flag.

Recon & Enumeration

  • Initial gobuster attempt used an invalid subcommand:
    gobuster url 10.64.185.189 -w /root/Desktop/Tools/wordlists/dirbuster/directory-list-1.0.txt
    

    → errored (not a real scan, dir is the correct mode).

  • Correct directory brute-force, small wordlist — no hits:
    gobuster dir -u http://10.64.185.189:8080 -w /root/Desktop/Tools/wordlists/dirbuster/directory-list-1.0.txt
    
  • Retried with a larger wordlist — still no hits:
    gobuster dir -u http://10.64.185.189:8080 -w /root/Desktop/Tools/wordlists/dirbuster/directory-list-2.3-medium.txt
    
  • Manually inspected the homepage via browser dev tools and curl -I:
    curl -I http://10.64.185.189:8080/
    

    Response headers revealed:

    Server: Werkzeug/3.0.1 Python/3.12.3
    Content-Disposition: inline; filename=index.html
    

    This indicated the app was serving raw files off disk (Flask send_file/send_from_directory pattern) rather than templated routes — a strong path-traversal signal.

  • Page source showed only one real link: /booking (404s), and a footer tag reading “guest experience platform · build staging” — suggested a non-production build with leftover exposure.

  • Checked for exposed .git directory — found it accessible:
    curl -s http://10.64.185.189:8080/.git/HEAD
    curl -s http://10.64.185.189:8080/.git/config
    

Exploitation

  • Dumped the exposed .git directory with wget:
    wget --mirror -I .git http://10.64.185.189:8080/.git/
    
  • git checkout .
  • Recovered the repo contents and found the flag inside.

Dead Ends & Mistakes

  • gobuster url — invalid mode, wasted a run before realizing dir was needed.
  • Two full gobuster runs (small and medium wordlists) against / turned up nothing — the vulnerable path wasn’t in either wordlist wordlist and wasn’t discoverable by brute force at all.
  • Chased path traversal via curl "http://10.64.185.189:8080/../../../../etc/passwd" — curl normalizes ../ client-side by default, so the request silently became GET /etc/passwd and returned a plain 404. Retried with --path-as-is and URL-encoded traversal (%2e%2e%2f...) — still no good, traversal was not the actual vector for this box.
  • Misread a resource://content-accessible/plaintext.css reference in browser dev tools as a server-side path — it was actually Firefox’s own internal stylesheet for rendering plain-text/404 responses, not anything hosted by the target.

Flags / Answers

  • Flag captured via .git dump (contents not recorded here).

Lessons Learned

  • Really struggled with this one despite the “Very Easy” rating — spent a long time on gobuster/wordlist troubleshooting and path traversal attempts before the actual vector (exposed .git directory) clicked.
  • Directory brute-forcing isn’t guaranteed to reveal everything — .git exposure is worth checking early and directly rather than relying on wordlists to stumble onto it.
  • curl normalizes ../ in URLs by default — need --path-as-is to test traversal payloads for real.
  • Response headers (Content-Disposition: filename=..., Server:) are worth checking immediately — they tipped off the file-serving pattern well before traversal/git testing began.
  • When a page’s own links all 404, treat that as a signal to look at the app’s build/deployment artifacts (.git, source maps, etc.) rather than continuing to brute-force paths.
← Back to journal