PEP: SMTP TutorialSMTP stands for Simple Mail Transport Protocol and it defines the commands and sequence of events that must occur when one computer connects to another one to send mail. The purpose of this document is to walk you through a sample SMTP session so that you can see how easy it is for people to abuse it.
Note that SMTP is used both when a client program (e.g.: Eudora, Outlook Express) connects to a server to send mail, and when one server connects to another server to pass mail along. The protocol is exactly the same.
The SMTP Exchange:
|The sending computer does this...||Then the receiving computer does this...||Notes|
|An SMTP session begins with the sending computer connecting to the receiving computer on port 25. No data is sent at this point.|
|220 islandnet.com ESMTP server ready.||All responses form the receiving computer will start with a number like '220' or '550', etc. These numbers are result codes, and that's how the sending computer knows if a command worked or failed. The text that follows the result code is irrelevant.|
|HELO hostname.mydomain.com||The first command sent to the receiving computer is the HELO command (or EHLO). It is followed by the full hostname of the sender's computer.|
|250 mail.islandnet.com Hello hostname.mydomain.com [111.222.333.444]||The receiving computer acknowledges the sender's HELO command and gives permission to continue.|
MAIL FROM:||The sender next specifies who the message is from via the MAIL FROM: command. Note that the value given here is known as the "envelope from" value and it has nothing at all to do with the message's From: header. The value given here will usually show up in one of the Received: headers, and it's also the value that goes into the Return-Path: header.|
||The receiver will normally perform some basic tests on the address and either reject it or accept it at this point. These checks might include basic syntax as well as checking to ensure that the domain part exists and has a valid MX entry for it (having an MX entry means that the domain has a mail server listed that will handle email that is addressed to the domain).|
TO:||Next the sender specifies the recipient's address via the RCPT TO: command. Note that this is known as the "envelope to" value and has nothing at all to do with the message's To:, Cc:, or Bcc: headers. The value given here will usually show up in one of the Received: headers, and on our server we also place it in the Envelope-To: header.|
250 ||The receiving system will normally verify that the address given is local and either accept or reject it at this point. A properly configured mail server will reject any recipients that are not local to the server (unless they come from a local user of course), while an "open relay" will accept and attempt to deliver mail for any recipient, local or not. If there are multiple recipients then then the sender will issue another RCPT TO: command for each one, and each one may be accepted or rejected individually.|
|DATA||The sender has been cleared to send the message, so it issues the DATA command to indicate that the actual message is to follow.|
|354 Enter message, ending with "." on a line by itself||The receiving system gives the go ahead to begin sending the message.|
From: Santa Clause
To: Naughty List
Subject: Coal for Christmas!
|The sender now sends the actual message. The message headers come first, followed by a blank line, and then the body of the message. A single dot on a line by itself marks the end of the message. Note that the From: and To: headers can contain anything at all and have no bearing on where the message winds up (this is controlled by the previous RCPT TO commands).|
|250 OK||The receiving system acknowledges receipt of the message. If the sender has more mail to deliver to this server it can start over by issuing another MAIL FROM: command. If it's finished it will issue the QUIT command and close the connection.|
The commands you type are in bold, everything else is not. Replace YOUR_ADDRESS with your actual e-mail address. If you do it correctly, you should get an e-mail from "Bugs Bunny" that doesn't contain your address in the To: header at all.
telnet mail.islandnet.com 25|
220 Islandnet.com ESMTP server ready
250 mail.islandnet.com Hello x [YOUR_IP_ADDRESS]
354 Enter message, ending with "." on a line by itself From: Bugs Bunny
To: Daffy Duck
Subject: Loony Toons!
. 250 OK id=1778te-0009TT-00
221 mail.islandnet.com closing connection
After trying out this example and seeing the results, you should be able to understand how a spammer can send you mail that doesn't appear to be addressed to you, or how certain viruses send themselves out and make it appear like they came from someone else entirely (hint: you could have put any address you wanted after the MAIL FROM: command, just so long as it's from a valid domain). The *only* piece of information that you can rely on is the IP address, which will show up in the top-most Received: header. And even that is useless for tracking if the sender took advantage of an open relay or proxy server.
- The only value that controls where a message goes is the one that
is specified in the RCPT TO: command. The To:, Cc:, and Bcc: headers
can contain anything at all. When you send a message using a typical
mail program, you enter the recipient's address in the To: field and
your mail client uses that when issuing the RCPT TO: command, but
that's just something that happens behind the scenes to make things
easier for you.
- The value you specify in the MAIL FROM: command is where any and
all bounces will go. Spammers will often pick a random address from
their mailing list and use it here. That way it looks like the spam
came from someone else, and all the error messages and angry responses
will go to this innocent person instead. If you've ever received a
complaint or a bounce for a message you never sent, this is probably
- A secure SMTP session is exactly the same, except that
the sending machine's first command after HELO (or EHLO) will be
STARTTLS, which tells the server to switch into secure mode. From
that point on, everything sent between the two systems will be
encrypted. If you try the example above and issue the STARTTLS
command, it won't work (unless you know how to perform complex
data encryption in your head :-)