SMTP Testing
This is a nice little tutorial meant for people who may be new to
the world of email messaging, or those who need a way to set up a test
environment for email.
This blog post will cover:
- Creating an smtp-sink to receive emails and confirm connections
- Manually sending emails to a Message Transfer Agent (MTA) using telnet
- Using PyEmailTest.py to test email flow to an smtp-sink, MTAs, or email security technologies
Why?
Personally, I needed a way to quickly diagnose whether or not
security products were successfully sending email notifications to their email
server. Rather than configure my own full blown email server, I discovered that
Postfix has a handy little built in tool called smtp-sink. This tool’s sole
purpose in life is to act like a vacuum and suck up any emails thrown at it. By
default, smtp-sink discards all received emails, but we are going to save these
emails to verify their content. The choice is up to you though.
Note: Please visit http://www.postfix.org/smtp-sink.1.html for smtp-sink’s
full capabilities. Configurations such as sending bounce messages (non-delivery
reports), variable MTA settings, and more are available for your
experimentation.
My Environment
For
this project, I used the following environment:
Machine
|
Purpose
|
IP address
|
Ubuntu Virtual
Machine
|
smtp-sink
|
192.168.254.167
|
Virtual Security
Appliance
|
Send SMTP
notifications
|
192.168.254.149
|
Mint Virtual
Machine
|
Manual Email
Testing
|
192.168.254.169
|
Note: I
used VMware Workstation for my environment. You can use the free VMware Player
or the VirtualBox for your environment. To make sure the Virtual Machines could
communicate with each other, I placed all of their network adapters on the same
VMnet which essentially connects them to a hub on the same subnet. Please leave
a comment if you need assistance setting this up. I also used DHCP to
automatically configure the IP addresses. To view ip addresses a Linux machine,
use the command ifconfig.
Installing smtp-sink On Ubuntu
smtp-sink is a tool included with the standard installation of
Postfix. To install Postfix on a standard version of Ubuntu, use the command sudo apt-get install postfix. This will automatically install Postfix on
your machine from Ubuntu’s repositories.
Since you are DOing this command as Super-User (sudo), Ubuntu will
prompt for your admin password. Ubuntu may also ask you to confirm your
decision to use disk space.
Read the different configuration types if you desire. We are going
to choose “Local only” in the next step. I haven’t worked with the other
configurations so let’s avoid them for now.
Use the left and right arrow keys to highlight <Ok> and
press Enter to accept.
Use
the left, right, up, and down arrow keys to choose “Local only” and then press
Enter on <Ok>.
For
our purposes, we are not concerned with how emails are handled by domain since
we are dropping them. You can leave the default here or change it if you wish.
The
installation process should finish as shown above. Now we are ready to turn on
the smtp-sink to receive emails.
Running smtp-sink
The
only information you need to know to run smtp-sink is your machine’s IP address
and your working directory since that is where you will be saving the emails
to. Use the ifconfig command from before to find your IP address and use the
sequence below to make a new directory for this testing:
Now
that we know my ip address is 192.168.254.167 and we are working out of our new
EmailTest directory, let’s start smtp-sink with the following command, filling
in your information for the <variables>.
sudo smtp-sink –u <YourUserName> -d –c <YourIPAddress>:25
100
Example command that I ran:
sudo
smtp-sink –u dave –d –c 192.168.254.167:25 100
sudo
|
“Super-User Do”
allows us to run this command with admin or root privileges
|
smtp-sink
|
This is the
program we are running, it was installed automatically when we installed
postfix
|
-u <YourUserName>
|
Since we are
running with sudo, smtp-sink needs to know which user’s privileges to use.
Use the username that appears at the beginning of the command line prompt
|
-d
|
Signals that we
would like to dump each message to a new file in the current directory. If we
do not use this option, all received emails are discarded.
|
-c
|
Makes a counter
that iterates when an email is received. This does not appear to work when
the –d option is used, but it is required to run.
|
<YourIPAddress>:25
|
*Make sure to
use the IP address of your machine
running smtp-sink!*
IP address of
the port we are using to receive emails on and port number. The IP should be
that of your eth0 interface found in ifconfig and the default port for SMTP
is tcp 25, so we will use that.
|
100
|
The command
requires a number be entered here as a backlog which is defined as “The
maximum length the queue of pending connections, as defined by the listen(2) system call.” This
is not important to us so let’s just keep it at 100.
|
After
running this command, the terminal will just sit there and listen. We need to
let this run and not interrupt it. You may open another terminal or tab if you
would like to run other commands.
In
another terminal window, running the command nautilus /home/dave/EmailTest opens Ubuntu’s GUI file browser. We
can now watch this as we send emails to smtp-sink.
Note: Other
versions of Linux may use other GUI file browsers than Nautilus. It may be best
to find the icon on your desktop.
Sending Emails To smtp-sink From My Virtual Security Appliance
I
realize you may not have a virtual security appliance or email sending
application (not yet anyway) but I feel compelled to describe my first
validation of smtp-sink.
I
logged into my appliance and configured the following settings for sending
email notifications:
Recipient
Address
|
RecipientAddress@TestDomain.com
|
Sender Address
|
SenderAddress@TestDomain.com
|
SMTP Server
|
192.168.254.167
|
SMTP Server Port
|
25
|
Sure
enough, when I sent a test message, it showed up in the EmailTest directory on
Ubuntu.
Sending Emails via Telnet
But
Dave, I don’t have a virtual security appliance capable of sending test emails!
I
realize not everyone has access to hardware or software (not yet anyway!) that
can readily send emails on demand to try out this smtp-sink. Have no fear! Next
we are going to use Telnet to manually send emails to the smtp-sink.
I found
out not too long ago that you can use Telnet to connect directly to the MTA
that is being run on an email server. In our scenario, postfix is our MTA and
since we are using smtp-sink, our MTA will receive the emails and pretend it is
going to forward them to their true destination.
We are
going to telnet from our Mint VM to the smtp-sink which is listening on
Ubuntu’s port 25. You can also use your host machine for this telnet session.
If you are using Windows, you will need a telnet client such as PuTTY.
Note:
You must telnet to the IP address of your
Ubuntu machine running smtp-sink
The
simple command telnet <YourMTAIPAddress>
25 will open a connection from Mint to smtp-sink. The “220” indicates a
successful connection. You can find out how to decipher MTA Response Codes at http://email.about.com/cs/standards/a/smtp_error_code.htm.
By
using SMTP Commands such as the ones described at http://www.yuki-onna.co.uk/email/smtp.html we can send this message to
smtp-sink.
If you
follow the script above, you should see another message appear in Ubuntu’s
EmailTest Directory!
Note: I
have not read how to decipher the file names, so I keep track of which files
are newest by arranging them by modification date by “right click” >
“Arrange Items” > “By Modification Date” as shown below. This puts new
messages at the end.
Let’s
open up this email file and see what we can find.
Just as
you may have expected, all the information from the Telnet session made it into
the message. Notice how even though you can spoof (fake) the sender’s address,
you cannot adjust the Client Address that originally sent the email. This
header information is how forensic analysts can track down spoofed emails.
Sending More Test Emails
Wow, we
just sent a customized email! Okay, that
may not be exciting enough to warrant an exclamation point, but I thought it
was neat the first time I saw it work.
Keep in
mind, the true goal of testing these emails is to make sure connections are
open to real email servers and those servers are then routing messages
properly. Telnet-ing to a server is great for testing a connection and sending
simple emails, but what if you wanted to test the capacity of an email server,
or make sure it was forwarding or even analyzing/filtering attachments
properly? It sounds like we need a tool for this.
I have
heard of people using deprecated versions of Outlook Express and Java based
tools to manually send emails to a specific Email Server IP. After trying to
find a secure version of Outlook Express and not wanting to use Java due to
cumbersome version installs and security risks, I decided I wanted my own tool
to send emails my way. Special thanks though to Finn Ramsland, a co-worker of
mine who wrote an email script for a different purpose. I borrowed a couple lines
of code from that script. Thanks, Finn!
Note:
Cloning existing tools is a great way to sharpen your scripting skills while
being able to customize your own features. Use caution with copyrighted or
patented software though. I’m no legal expert so talk to an expert if
necessary.
I now
present to you, for lack of a better name: PyEmailTester. I created this
command line based tool to send customizable emails to any SMTP MTA that can be
reached without authentication. At the time of this writing, this tool needs to
be run on either a Windows machine or
a Linux machine with python’s Tkinter package installed. Tkinter is used for
the file selection pop up box to choose which file to attach.
To
install Tkinter on Linux, use the command sudo
apt-get install python-tk
When
using this tool, the following items are configurable:
- Sender Address
- Recipient Address
- Subject
- Message Body
- Server Address
- Port Number to connect to
- Attachment – You can add one attachment
- Number of times to continuously send this email – for capacity tests
Use
Cases for this tool:
- Testing connectivity and basic mail flow
- Testing server capacity
- Submitting malicious emails to a mail filter or content analyzer
Tool Demo
Before
we start using this tool, let’s delete the older emails so we don’t get
confused.
There
we go, fresh and clean again.
To get
started with PyEmailTest, you can find it on my GitHub at https://github.com/davidpany/PyEmailTest. If know how to pull
repositories with git, that works. If you have no idea what git or GitHub is,
just download a zip of the script from https://github.com/davidpany/PyEmailTest/archive/master.zip.
After
downloading and unzipping the file on a different VM (I’m using Mint but you
can use any other OS as long as python and Tkinter are properly installed), we
can see the script is ready for action.
To run
this script on Linux, open a Terminal, change your working directory to where
you extracted the .py script, and run the command python PyEmailTest.py
As
shown above, the script will ask if you want to use the default values for
Sender, Recipient, Subject, Message Body, and Port. If you choose to not use the Default message
settings, you can customize each of these fields.
You must always enter in the Server address you want to send to. For us, this will be the IP address smtp-sink is listening on.
You must always enter in the Server address you want to send to. For us, this will be the IP address smtp-sink is listening on.
Then
you can choose to add an attachment. If you type “yes”, a Tkinter popup will
appear. For now, let’s just attach the script itself. Choose the PyEmailTest.py
script and click on “Open”
The
tool will then ask how many times you would like to send this message. I have
entered 3. This will resend the same message with the same attachment 3
continuous times.
Sure enough, back on the smtp-sink Ubuntu machine, 3 emails
were received and stored in the EmailTest directory.
Looking at the Emails
Opening
one of these email files in our text editor shows the default settings defined
by the script as well as the sending client’s IP of 192.168.254.169 or whatever
IP your sending machine was set to. Information regarding the Subject, Body,
and Attachment are also given such as MIME Version, Encoding type, and
Content-Disposition. For the filename, the whole path of upload directory is
shown. I’m not sure if this is true for emails sent with traditional email
clients or not, but it is scary in this situation.
So
where did the attached python script go? Well it turns out that SMTP email was
never designed to send files. It was created only send to send plaintext ASCII.
To send special fonts, pictures, and attachments; objects are encoded to a
format that consists only of readable ASCII characters. Shown for the
attachment above, its encoding type is base64. This means that long block of
random characters contains our file. All we need to do is copy that entire
block to the website www.base64decode.org and let it do the work.
Note:
Be sure to copy to the end of the character block as indicated below. It is
also common to see one or two equal signs (=) at the end of a base64 string as
padding. Include them as well!
Now we
can see the readable beginning of the python code that allowed us to send the
message!
Websites
such as http://www.motobit.com/util/base64-decoder-encoder.asp even have the option to write
the output to binary file so don’t have to worry about copy and pasting errors
when trying to save a non ASCII file.
Wrap Up
I hope you enjoyed this little tutorial. If you are new to
this, I hope it was easy to follow. If you are a ninja, thank you for reading
and I hope you may have found something useful here.
You should have learned how to:
- Create an smtp-sink to receive emails and confirm connections
- Manually send emails to a Message Transfer Agent (MTA) using telnet
- Use PyEmailTest.py to test email flow to an smtp-sink, MTAs, or email security technologies
Thanks
for reading!
-Dave