# SMTP User Enumeration

- **URL:** https://hackindex.io/services/smtp/vulnerability-discovery/smtp-user-enumeration
- **Path:** SMTP > Vulnerability Discovery
- **Up:** [Vulnerability Discovery](https://hackindex.io/services/smtp/vulnerability-discovery.md)
- **Published:** 2026-03-29
- **Updated:** 2026-03-29

SMTP user enumeration confirms which email addresses exist on the target mail server using the VRFY, EXPN, and RCPT TO commands. A confirmed user list enables targeted password spraying against OWA, SMTP submission, and other services. RCPT TO is the most reliable method: it works even when VRFY and EXPN are explicitly disabled, because recipient validation happens as a normal part of the mail flow. Run this after [SMTP enumeration](https://hackindex.io/services/smtp/enumeration/smtp-enumeration) confirms which commands the server supports.

- Check Which Methods Are Available
- Manual VRFY Testing
- Manual RCPT TO Testing
- Automated Enumeration with smtp-user-enum
- Wordlist Selection
- False Positive Filtering

## Check Which Methods Are Available

The EHLO response shows whether VRFY is advertised. EXPN and RCPT TO are always worth testing regardless:

```bash
echo -e 'EHLO test\nQUIT' | nc -nv $TARGET_IP 25 | grep -iE 'vrfy|expn|auth'
# 250-VRFY
# 250-AUTH PLAIN LOGIN
```

## Manual VRFY Testing

Test a few known accounts manually before running automated tooling to confirm response patterns:

```bash
echo -e 'EHLO test\nVRFY admin\nVRFY root\nVRFY postmaster\nVRFY nonexistent123\nQUIT' | nc -nv $TARGET_IP 25
# 250 2.0.0 admin
# 550 5.1.1 <root>: Recipient address rejected
# 250 2.0.0 postmaster
# 550 5.1.1 <nonexistent123>: Recipient address rejected
```

250 confirms the user. 550 is a strong negative. 252 means the server won't verify but will accept the message: this is not a positive confirmation, do not treat it as one. Establish the positive and negative response patterns from a known-good and known-bad username before running bulk enumeration.

## Manual RCPT TO Testing

When VRFY is disabled, RCPT TO still validates recipients. The server must confirm or deny the recipient before queuing the message:

```bash
echo -e 'EHLO test\nMAIL FROM:<probe@test.com>\nRCPT TO:<admin@$DOMAIN>\nRCPT TO:<nonexistent@$DOMAIN>\nQUIT' | nc -nv $TARGET_IP 25
# 250 2.1.5 Ok
# 550 5.1.1 <nonexistent@company.com>: Recipient address rejected: User unknown
```

## Automated Enumeration with smtp-user-enum

Use RCPT mode first. It is the most reliable across different server configurations. Provide the domain with `-D` to append it to usernames from the wordlist:

```bash
smtp-user-enum -M RCPT -U /usr/share/seclists/Usernames/top-usernames-shortlist.txt -D $DOMAIN -t $TARGET_IP -p 25
# [*] Trying RCPT method...
# [+] admin@company.com exists
# [+] postmaster@company.com exists
# [+] info@company.com exists
```

```bash
smtp-user-enum -M VRFY -U /usr/share/seclists/Usernames/top-usernames-shortlist.txt -t $TARGET_IP -p 25
```

```bash
smtp-user-enum -M EXPN -U /usr/share/seclists/Usernames/top-usernames-shortlist.txt -t $TARGET_IP -p 25
```

## Wordlist Selection

Choose wordlists based on what you know about the target. Generic username lists work for initial discovery, but domain-specific lists based on naming conventions are more effective:

```bash
# Generate firstname.lastname variants from a names list
python3 -c "
names = [('john','smith'),('jane','doe'),('bob','jones')]
for f,l in names:
    print(f'{f}.{l}@$DOMAIN')
    print(f'{f[0]}{l}@$DOMAIN')
    print(f'{f}_{l}@$DOMAIN')
" > /tmp/custom_users.txt
smtp-user-enum -M RCPT -U /tmp/custom_users.txt -t $TARGET_IP -p 25
```

## False Positive Filtering

Some servers accept all RCPT TO addresses regardless of whether the user exists: catch-all configurations. Detect this by testing a clearly random address and checking whether it also returns 250:

```bash
echo -e 'EHLO test\nMAIL FROM:<probe@test.com>\nRCPT TO:<xyzzy99999randomuser@$DOMAIN>\nQUIT' | nc -nv $TARGET_IP 25
# 250 2.1.5 Ok
```

A 250 for a clearly invalid address confirms catch-all configuration: RCPT TO enumeration produces only false positives on this server. Switch to VRFY if available, or rely on other sources for user discovery such as OSINT and LinkedIn scraping.

## References

- [smtp-user-enum](https://github.com/pentestmonkey/smtp-user-enum) - VRFY, EXPN, and RCPT mode user enumeration with domain support
- [SecLists: Usernames](https://github.com/danielmiessler/SecLists/tree/master/Usernames) - Username wordlists for SMTP and other service enumeration
