Why Enumerate a Mail Server?
SMTP (Simple Mail Transfer Protocol) runs on port 25. Its job is to send and receive email.
But SMTP has a feature that was never meant to be a security hole: it can verify whether a username exists on the system.
This turns a mail server into a username oracle. Ask it “does this user exist?” and it’ll tell you yes or no. Do this thousands of times with a wordlist, and you have a list of valid accounts.
The VRFY Command
SMTP supports a command called VRFY (verify). Send it a username, and the server tells you if that mailbox exists.
Response Codes
The server’s response code tells you everything:
| Code | Meaning | What it tells you |
|---|---|---|
| 252 | User exists | Server will accept mail for this address |
| 550 | User unknown | No such mailbox |
| 251 | User not local | Address is forwarded elsewhere |
Manual Enumeration
Connect to the SMTP server with Netcat:
nc -nv 10.10.10.50 25Then try usernames one by one:
VRFY root
VRFY admin
VRFY www-data
VRFY backup Watch the response codes. 252 means you found a valid user.
The EXPN Command
EXPN (expand) asks the server for the members of a mailing list. If the server supports it, this can reveal even more usernames.
EXPN staff Not all servers support EXPN, but when they do, it’s a faster way to find groups of users.
Automated Enumeration
Nmap NSE Scripts
Nmap has built-in scripts for SMTP enumeration:
nmap --script smtp-enum-users 10.10.10.50 -p 25This tries VRFY, EXPN, and RCPT TO methods automatically against a default user list.
Combine with other SMTP scripts for a fuller picture:
nmap --script smtp-enum-users,smtp-commands,smtp-open-relay 10.10.10.50 -p 25smtp-commandsshows supported commands (tells you if VRFY is enabled)smtp-open-relaychecks if the server can be used to relay mail (useful for phishing later)
smtp-user-enum
A dedicated SMTP user enumeration tool. Install it from the GitHub repo on any distro:
smtp-user-enum -M VRFY -U usernames.txt -t 10.10.10.50-M VRFYselects the method (also supportsEXPNandRCPT)-Uprovides a username wordlist-tsets the target
It handles timeouts, retries, and reconnects automatically. Much faster than manual Netcat.
Scripting It with Python
For full control, a simple Python script does the same thing:
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[2], 25))
banner = s.recv(1024)
print(banner)
user = sys.argv[1].encode()
s.send(b'VRFY ' + user + b'
')
result = s.recv(1024)
print(result)
s.close()Run it:
python3 smtp_vrfy.py root 10.10.10.50
python3 smtp_vrfy.py admin 10.10.10.50Extend this to read from a wordlist and you have an automated user enumerator.
SMTP from Windows
On a Windows machine, Test-NetConnection confirms port 25 is open but can’t interact with SMTP directly.
For actual SMTP interaction, you need a Telnet client:
dism /online /Enable-Feature /FeatureName:TelnetClientThis requires admin privileges. If you can’t install it, grab telnet.exe from another machine (C:\Windows\System32\telnet.exe) and transfer it.
Then:
telnet 10.10.10.50 25
VRFY rootWhy This Matters
Valid usernames feed into later attack phases:
- Password spraying - try common passwords against confirmed usernames
- Brute-force attacks - knowing the username is half the battle
- Social engineering - confirmed email addresses for phishing
- Credential stuffing - cross-reference with leaked password databases
A mail server that responds to VRFY is handing you a user directory. Many modern servers disable VRFY, but legacy systems and misconfigurations still expose it.