| Tested on | Kali GNU/Linux Rolling 2026.2 (kali-rolling) |
|---|---|
| Package | smtp-user-enum 1.2-1kali4nmap 7.99+dfsg-1kali1metasploit-framework |
| Applies to | Kali Linux |
| Lab environment | Kali + Metasploitable 2 on VirtualBox host-only — pentest lab setup |
| Privilege | Normal user for smtp-user-enum and Nmap; sudo for package installs |
| Scope | Active SMTP enumeration with smtp-user-enum (VRFY, RCPT TO), Nmap SMTP NSE scripts, and Metasploit smtp_enum against Metasploitable 2 Postfix on port 25. Covers banner and command discovery, username guessing, and open-relay checks. Does not cover SMTP exploitation, phishing campaigns, or cloud mail API abuse. |
| Related guides | Nmap command cheat sheet Metasploit tutorial Learn hacking with Metasploitable 2 |
SMTP enumeration asks a mail server which recipient names appear valid. On misconfigured hosts, VRFY and RCPT TO responses can help you build a candidate list for further authorized investigation in an ethical hacking lab. Those addresses also feed realistic target lists when you wire SMTP into Gophish sending profiles.
This guide walks through three enumeration paths on Kali Linux against Metasploitable 2 Postfix on port 25. Along the way I explain what each step checks and what a good result looks like. Every command and output block below was captured on that layout.
What is SMTP enumeration in ethical hacking?
The rest of this guide builds a list of recipient names Postfix appears to accept on port 25. You send VRFY, EXPN, or RCPT TO probes — not mail — and read whether the server treats each name as valid.
SMTP (Simple Mail Transfer Protocol) normally relays mail between mail servers on TCP port 25, while mail clients commonly submit outgoing messages on TCP port 587. SMTP enumeration in penetration testing means sending protocol commands to learn:
- Which usernames or mailboxes the server accepts
- Whether VRFY, EXPN, or RCPT TO are enabled
- Whether the host is an open relay
Enumeration is reconnaissance, not mail delivery. Valid names often appear in other services on the same lab host (SSH, Samba, web apps), which makes SMTP worth checking early alongside banner grabbing on port 25.
Pen testers focus on three SMTP verbs for user discovery:
| Command | Purpose |
|---|---|
| VRFY | Ask the server to verify whether a mailbox or user name exists |
| EXPN | Expand a mailing-list alias to member addresses (often disabled) |
| RCPT TO | Set a recipient during an SMTP session; invalid users may trigger a distinct error |
Metasploitable Postfix advertises VRFY in its EHLO banner. That is intentional misconfiguration for lab practice, not a pattern you should expect on hardened production mail servers.
Kali lab setup
Set up the lab once so every tool hits the same Postfix listener with the same TARGET and DOMAIN. You end up with variables and packages ready — no need to retype IPs in each command block.
Before you run the examples:
- Kali Linux with the tools below installed
- Metasploitable 2 on the same host-only or internal network as Kali
- Comfort reading SMTP status codes (
250success,550user unknown)
Install the packages if they are missing on your Kali image:
sudo apt update
sudo apt install -y smtp-user-enum nmap metasploit-frameworkMetasploitable 2 network, target IP, and domain variables
| Item | Attacker (Kali) | Target (Metasploitable 2) |
|---|---|---|
| Hypervisor | Oracle VirtualBox (shared) | Same host |
| Lab network | Host-only / internal 192.168.56.0/24 |
Same subnet |
| Lab IP | 192.168.56.115 on eth1 |
192.168.56.114 (TARGET) |
| SMTP service | Connect to "$TARGET":25 |
Postfix on port 25 (587 closed) |
| Banner | EHLO / Nmap smtp-commands |
metasploitable.localdomain, VRFY enabled |
| Lab users | smtp-user-enum -u msfadmin |
VRFY and RCPT confirm msfadmin |
Substitute your own addresses if VirtualBox assigns a different range. Set the target once, then reuse it in every command:
TARGET=192.168.56.114
DOMAIN=metasploitable.localdomainThe DOMAIN value matches the banner hostname on Metasploitable and is used when enumerating full email addresses with smtp-user-enum -D. The tool sections below reuse TARGET and DOMAIN — only the enumeration program changes.
Scan port 25 with Nmap
Brute forcing usernames on a closed mail port wastes time. First confirm Postfix is listening and read which SMTP verbs it advertises — especially VRFY, which unlocks the user-guessing steps below.
Verify port 25 is open and fingerprint the daemon before you enumerate users:
nmap -Pn -p 25 -sV "$TARGET"-Pn skips host discovery and treats the lab address as online.
PORT STATE SERVICE VERSION
25/tcp open smtp Postfix smtpdPostfix on Ubuntu matches the Metasploitable mail stack. Note whether submission port 587 is open on your image; this lab showed 587/tcp closed.
List SMTP verbs with smtp-commands
The Nmap smtp-commands script reads the EHLO response:
nmap -Pn -p 25 --script smtp-commands "$TARGET"PORT STATE SERVICE
25/tcp open smtp
|_smtp-commands: metasploitable.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSNThe VRFY keyword in that line means the server may confirm usernames on request. Port 25 is open and the EHLO capabilities are recorded — you can enumerate users next.
Compare SMTP enumeration tools
The sections below walk smtp-user-enum, Nmap scripts, and Metasploit smtp_enum against the same Postfix listener. Use this table to pick a path before you scale up wordlist size.
| Tool | Best for | Typical output |
|---|---|---|
| smtp-user-enum | Fast VRFY / RCPT / EXPN sweeps with -u or -U |
IP: username exists per hit |
Nmap (smtp-commands, smtp-open-relay) |
Banner verbs and relay policy | EHLO capability list; relay test summary |
Nmap (smtp-enum-users) |
Scripted user guess with userdb and {VRFY} |
Account list or “Couldn't find any accounts” |
Metasploit smtp_enum |
VRFY-first scan with USER_FILE |
Banner line plus Users found: list |
Start with smtp-commands to see whether VRFY is advertised, then run smtp-user-enum before spending time on full Metasploit wordlist sweeps.
Enumerate users with smtp-user-enum
smtp-user-enum automates VRFY, EXPN, and RCPT TO against one name or a whole wordlist. A line like IP: username exists means the server classified that candidate as valid — paste those names into your report as SMTP-positive candidates, not proven login accounts.
List modes with smtp-user-enum -h when you need EXPN or RCPT TO instead of VRFY.
Verify one lab user with VRFY
Test a username you expect on Metasploitable (msfadmin):
smtp-user-enum -M VRFY -u msfadmin -t "$TARGET"Lowercase -u checks a single name. Uppercase -U points at a wordlist file.
192.168.56.114: msfadmin existsexists means smtp-user-enum classified the SMTP reply as positive for that candidate. The name may represent a local account, alias, or mailbox; it does not prove that the same name can log in through SSH or that its password is weak.
Enumerate users from a wordlist
Scan many names from the Metasploit wordlist collection (path on Kali uses wordlists, not wordlist):
smtp-user-enum -M VRFY -U /usr/share/wordlists/metasploit/common_roots.txt -t "$TARGET"A full run against common_roots.txt (4,730 names) took about 48 seconds in this lab and reported 26 valid names (trimmed):
192.168.56.114: root exists
192.168.56.114: mail exists
192.168.56.114: postgres exists
192.168.56.114: nobody exists
192.168.56.114: user exists
...
26 results.
4730 queries in 48 seconds (98.5 queries / sec)Names such as root, mail, postgres, and nobody are system accounts or local recipients on this lab image. Treat them as SMTP-positive candidates, not automatically as interactive login users.
msfadmin is not in common_roots.txt, so add known lab accounts with -u or append them to a custom wordlist before you scan.
Enumerate email addresses with -D
When the server expects full addresses, pass the mail domain:
smtp-user-enum -M VRFY -D "$DOMAIN" -U /usr/share/wordlists/metasploit/common_roots.txt -t "$TARGET"192.168.56.114: root@metasploitable.localdomain exists
192.168.56.114: mail@metasploitable.localdomain exists
192.168.56.114: postgres@metasploitable.localdomain exists
192.168.56.114: user@metasploitable.localdomain existsTry RCPT TO when VRFY is disabled
On hosts that disable VRFY, RCPT TO may still leak valid users:
smtp-user-enum -M RCPT -u msfadmin -t "$TARGET"192.168.56.114: msfadmin existsOn Metasploitable, RCPT TO confirmed the same lab account as VRFY.
Enumerate with Nmap SMTP scripts
Nmap can list SMTP verbs, test open relay, and script user guesses in the same scan pass. After smtp-commands showed VRFY, these scripts check relay policy and whether Nmap’s smtp-enum-users agrees with smtp-user-enum on the same candidates.
Beyond smtp-commands, Nmap ships other SMTP NSE scripts. Confirm the three used in this walkthrough:
printf '%s\n' \
/usr/share/nmap/scripts/smtp-{enum-users,open-relay,commands}.nse/usr/share/nmap/scripts/smtp-enum-users.nse
/usr/share/nmap/scripts/smtp-open-relay.nse
/usr/share/nmap/scripts/smtp-commands.nseTwo of those scripts are useful for mail recon on authorized targets after you list supported verbs with smtp-commands.
Check for open relay
Misconfigured relays let anyone send mail through your server. Test only on systems you are permitted to assess:
nmap -Pn -p 25 --script smtp-open-relay "$TARGET"|_smtp-open-relay: Server doesn't seem to be an open relay, all tests failedMetasploitable Postfix did not relay mail for arbitrary domains in this run — expected for a basic lab image.
User enumeration with smtp-enum-users
The smtp-enum-users script guesses users with VRFY, EXPN, or RCPT TO. Pass smtp-enum-users.methods as a list (not a bare string) and supply candidates through the shared userdb argument — smtp-enum-users.usernames is not a valid script argument.
Build a small username file, then force VRFY only:
printf '%s\n' msfadmin root user > /tmp/smtp-nmap-users.txtnmap -Pn -p 25 --script smtp-enum-users \
--script-args 'smtp-enum-users.methods={VRFY},userdb=/tmp/smtp-nmap-users.txt' \
"$TARGET"| smtp-enum-users:
|_ Couldn't find any accountsOn this Postfix build, the corrected command still reported no accounts even though smtp-user-enum -M VRFY marked msfadmin, root, and user as exists. Prefer smtp-user-enum or Metasploit when you need reliable user guessing on the lab image.
Enumerate with Metasploit smtp_enum
Metasploit’s smtp_enum module walks a USER_FILE with VRFY first, then fallbacks when needed. A [+] Users found: line lists names the module verified — the same kind of candidate list smtp-user-enum builds, in framework output. It reads every line in USER_FILE literally and skips root during enumeration.
Build a short, reproducible candidate list:
cat > /tmp/smtp-lab-users.txt <<'EOF'
msfadmin
postgres
notarealuser
EOFRun the module non-interactively:
msfconsole -q -x "use auxiliary/scanner/smtp/smtp_enum; set RHOSTS $TARGET; set USER_FILE /tmp/smtp-lab-users.txt; run; exit -y"[*] 192.168.56.114:25 - 192.168.56.114:25 Banner: 220 metasploitable.localdomain ESMTP Postfix (Ubuntu)
[+] 192.168.56.114:25 - 192.168.56.114:25 Users found: msfadmin, postgres
[*] 192.168.56.114:25 - Scanned 1 of 1 hosts (100% complete)The [+] line lists names the module verified through its VRFY pass. notarealuser did not appear because VRFY rejected that candidate. Feed confirmed names into SSH or web login tests on the same host — only where you are authorized to continue.
Troubleshooting
When port 25 is closed, VRFY finds nothing, or Nmap disagrees with smtp-user-enum, check the table below.
| Symptom | Likely cause | Fix |
|---|---|---|
| Connection refused on port 25 | SMTP down or filtered | nmap -Pn -p 25 "$TARGET"; confirm Metasploitable is running |
No users from common_roots.txt |
Wordlist lacks lab accounts | Add msfadmin with -u or append to a custom USER_FILE |
smtp-enum-users reports no accounts |
Wrong methods syntax, wrong userdb, or script mismatch with Postfix |
Use smtp-enum-users.methods={VRFY} and userdb=/path/to/file; fall back to smtp-user-enum -M VRFY |
| VRFY fails but RCPT works | Server disabled VRFY only | Switch -M RCPT in smtp-user-enum |
| Metasploit module runs for a long time | Large USER_FILE |
Use a short cat <<'EOF' file with known candidates instead of full wordlists |
| Wordlist path not found | Wrong directory name | Use /usr/share/wordlists/metasploit/ on Kali |
References
- smtp-user-enum (Kali)
- Nmap
smtp-commandsscript - Nmap
smtp-open-relayscript - Nmap
smtp-enum-usersscript - Metasploit
smtp_enummodule (Rapid7) - Cloudflare — What is SMTP?
- Postfix
disable_vrfy_commandparameter - Metasploitable 2 documentation (Rapid7)
Summary
SMTP enumeration turns an open port 25 into a list of valid usernames before password attacks. In this lab you confirmed Postfix on Metasploitable, read VRFY in the EHLO banner, and enumerated accounts with smtp-user-enum (VRFY, RCPT TO, and -D addresses), Nmap smtp-commands and smtp-open-relay, and Metasploit smtp_enum.
smtp-user-enum and Metasploit proved the most reliable for discovering msfadmin and postgres on the lab image. Nmap’s smtp-enum-users script, even with methods={VRFY} and userdb, reported no accounts on this Postfix build while smtp-user-enum still marked the same candidates as exists. Treat every exists or Users found name as an SMTP-positive candidate for the next authorized step — SSH, web login, or DNS and service scans — not as proof of a weak password.
Disable VRFY on production mail listeners (disable_vrfy_command in Postfix), block unauthorized relay, and monitor bulk VRFY or RCPT patterns. Never run username sweeps against mail servers you are not permitted to test.

