SMTP Enumeration

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:

CodeMeaningWhat it tells you
252User existsServer will accept mail for this address
550User unknownNo such mailbox
251User not localAddress is forwarded elsewhere

Manual Enumeration

Connect to the SMTP server with Netcat:

nc -nv 10.10.10.50 25

Then 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 25

This 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 25
  • smtp-commands shows supported commands (tells you if VRFY is enabled)
  • smtp-open-relay checks 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 VRFY selects the method (also supports EXPN and RCPT)
  • -U provides a username wordlist
  • -t sets 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.50

Extend 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:TelnetClient

This 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 root

Why 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.