smtp-user-enum is a Perl tool designed to enumerate valid usernames on a mail server by abusing built-in SMTP commands. Many SMTP server implementations respond differently for valid versus invalid recipient/user names when queried with the VRFY (verify), EXPN (expand mailing list), or RCPT TO (recipient) commands — a classic username-enumeration side channel that has existed in the SMTP protocol since its earliest RFCs. smtp-user-enum automates testing a wordlist of usernames against a target mail server using whichever of these three methods is most effective, and reports back which usernames the server confirms as valid mailboxes.
This is particularly valuable during an assessment because a confirmed valid email/username list feeds directly into later attacks: password spraying against webmail/OWA/VPN portals, targeted phishing (in authorized red-team engagements), or brute-forcing other exposed services that share the same username namespace (AD, SSH, etc.).
Installation
# Kali Linux (preinstalled)
sudo apt update
sudo apt install smtp-user-enum -y
# Verify
smtp-user-enum -h
which smtp-user-enum
Syntax
smtp-user-enum -M <mode> -U <userlist> -t <target> [options]
Command-Line Options
| Option | Description |
|---|---|
-M mode | Enumeration method: VRFY, EXPN, or RCPT |
-U file | File containing usernames to test |
-u user | Test a single username instead of a list |
-D domain | Domain name to append/use for RCPT TO mode (e.g., example.com) |
-t target | Target IP address or hostname |
-T file | File containing multiple target IPs |
-p port | SMTP port to connect to (default 25) |
-w seconds | Timeout in seconds for each connection (default 5) |
-d | Add a delay (in seconds, combined with a numeric value) between each request |
-m n | Maximum number of connection retries |
-v | Verbose output |
-f address | Sender (“MAIL FROM”) address to use for RCPT mode |
-h | Display help message |
Basic Usage
smtp-user-enum -M VRFY -U /usr/share/wordlists/metasploit/unix_users.txt -t 192.168.56.101
Expected output:
Starting smtp-user-enum v1.2 ( http://pentestmonkey.net/tools/smtp-user-enum )
----------------------------------------------------------
| Scan Information |
----------------------------------------------------------
Mode ..................... VRFY
Worker Processes .......... 5
Usernames file ............ /usr/share/wordlists/metasploit/unix_users.txt
Target count .............. 1
Username count ............ 168
Target TCP port ........... 25
Query timeout .............. 5 secs
Target domain ..............
######## Scan started at Sun Jul 19 10:22:41 2026 #########
192.168.56.101: msfadmin exists
192.168.56.101: root exists
192.168.56.101: postgres exists
######## Scan completed at Sun Jul 19 10:22:47 2026 #########
------------------------------------------------------
3 results.
3 of 168 usernames found
Practical Examples
Example 1 — VRFY mode against a single target
smtp-user-enum -M VRFY -U /usr/share/wordlists/metasploit/unix_users.txt -t 192.168.56.101
192.168.56.101: msfadmin exists
192.168.56.101: root exists
192.168.56.101: sys exists
3 of 168 usernames found
Example 2 — Single-username quick check
smtp-user-enum -M VRFY -u root -t 192.168.56.101
192.168.56.101: root exists
1 of 1 usernames found
Example 3 — EXPN mode (mailing-list expansion)
smtp-user-enum -M EXPN -U userlist.txt -t 192.168.56.101
192.168.56.101: admin exists [admin@localhost]
2 of 50 usernames found
Example 4 — RCPT TO mode with a domain (common when VRFY/EXPN disabled)
smtp-user-enum -M RCPT -U userlist.txt -D corp.local -t 192.168.10.25
192.168.10.25: jdoe@corp.local exists
192.168.10.25: asmith@corp.local exists
2 of 500 usernames found
Example 5 — Scanning multiple mail servers from a target file
cat mail_servers.txt
# 192.168.10.25
# 192.168.10.26
smtp-user-enum -M RCPT -U userlist.txt -D corp.local -T mail_servers.txt
192.168.10.25: jdoe@corp.local exists
192.168.10.26: jdoe@corp.local exists
192.168.10.26: asmith@corp.local exists
3 of 1000 usernames found
Example 6 — Custom port (submission port 587)
smtp-user-enum -M VRFY -U userlist.txt -t 192.168.56.101 -p 587
192.168.56.101: msfadmin exists
1 of 168 usernames found
Example 7 — Adding delay between requests to evade rate-limiting/IDS
smtp-user-enum -M RCPT -U userlist.txt -D corp.local -t 192.168.10.25 -d 2
[scan proceeds slowly, 2 second delay between each request]
192.168.10.25: jdoe@corp.local exists
1 of 500 usernames found
Example 8 — Verbose mode showing raw SMTP responses
smtp-user-enum -M VRFY -u msfadmin -t 192.168.56.101 -v
CONN(0): 192.168.56.101 tcp/25 open
VRFY(0): msfadmin: 250 2.1.5 msfadmin <msfadmin@metasploitable.localdomain>
192.168.56.101: msfadmin exists
Example 9 — Custom sender address for RCPT mode
smtp-user-enum -M RCPT -U userlist.txt -D corp.local -t 192.168.10.25 -f admin@corp.local
192.168.10.25: jdoe@corp.local exists
1 of 500 usernames found
Example 10 — Increasing timeout for a slow/high-latency mail server
smtp-user-enum -M VRFY -U userlist.txt -t 192.168.56.101 -w 15
192.168.56.101: msfadmin exists
192.168.56.101: root exists
2 of 168 usernames found
Common Use Cases
- Building a validated employee/user email list for authorized phishing simulations or password-spraying attacks against OWA/webmail/VPN portals
- Confirming whether a legacy SMTP server exposes
VRFY/EXPN(a long-standing, well-known information-disclosure misconfiguration) - Cross-referencing SMTP-confirmed usernames against Active Directory or SSH accounts to identify shared credentials/namespace overlap
- Auditing mail servers as part of an external perimeter assessment for username-enumeration weaknesses
- Feeding a confirmed username list into brute-force tools (e.g.,
hydra) targeting the same mail server’s authentication (POP3/IMAP/SMTP AUTH)
Automation with Bash
#!/bin/bash
# smtp_enum_pipeline.sh - Try all three enumeration modes automatically and merge unique hits
TARGET="192.168.56.101"
USERLIST="/usr/share/wordlists/metasploit/unix_users.txt"
DOMAIN="corp.local"
OUT="smtp_valid_users.txt"
> "$OUT"
for mode in VRFY EXPN RCPT; do
echo "[*] Trying mode: $mode"
if [ "$mode" == "RCPT" ]; then
smtp-user-enum -M "$mode" -U "$USERLIST" -D "$DOMAIN" -t "$TARGET" 2>/dev/null | grep "exists" >> "$OUT"
else
smtp-user-enum -M "$mode" -U "$USERLIST" -t "$TARGET" 2>/dev/null | grep "exists" >> "$OUT"
fi
done
sort -u -o "$OUT" "$OUT"
echo "[+] Unique confirmed users saved to $OUT"
cat "$OUT"
Tips and Best Practices
- Try all three modes (
VRFY,EXPN,RCPT) in sequence — many modern mail servers disableVRFYbut still leak information viaRCPT TObehavior differences. - Use
-DwithRCPTmode whenever the target is a full mail domain rather than a bare hostname; without it, results will be unreliable. - Add
-d(delay) on production targets to reduce the chance of triggering rate-limiting, greylisting, or IDS/IPS alerts. - Use a curated, role-relevant username wordlist (e.g., SecLists’ common name-based lists, or an OSINT-derived list of employee names) rather than only generic Unix account lists, for corporate mail servers.
- Confirm findings with
-v(verbose) periodically to make sure you understand exactly which SMTP response codes are being classified as “exists” vs “not exists” — false positives/negatives can occur on non-standard SMTP implementations.
Troubleshooting
| Problem | Likely Cause | Solution |
|---|---|---|
Connection refused for every target | Port 25/587 filtered or SMTP service not present | Confirm with nmap -p25,587 <ip> |
| Every username reports “exists” | Server returns generic 250 for all RCPT TO regardless of validity (anti-enumeration hardening) | Cross check manually via telnet <ip> 25 and observe raw response codes; results may be unreliable |
| Zero usernames found despite valid accounts | VRFY/EXPN disabled and RCPT behaves identically for valid/invalid users | Try a different mode, or attempt authenticated enumeration via a different vector (LDAP, SMB) |
| Scan very slow | Default worker/delay settings, or high-latency target | Reduce -w timeout cautiously, or increase parallelism if the tool version supports it |
550 relaying denied errors for all attempts | Server requires MAIL FROM to be from an accepted domain | Set -f to an address on the target’s own domain |
References
- Original tool page (pentestmonkey): http://pentestmonkey.net/tools/user-enumeration/smtp-user-enum
- Kali Linux tool page: https://www.kali.org/tools/smtp-user-enum/
- SMTP protocol RFC 5321 (VRFY/EXPN commands): https://datatracker.ietf.org/doc/html/rfc5321
