Pentest - Everything SMTP
In this blog-post I am trying to demystify SMTP (at least for myself).
What exactly is it used for? What parties are involved? What about authentication and when? What attack surfaces are you opening with incorrect settings?
As you may have read in the other posts, I will most likely try to reflect my knowledge on specific topics or work on certain problems I face (mainly during work), where these blog-posts are aimed to help me.
This time it´s all about SMTP in regards of possible attacks and countermeasures, all from the point of view of an external attacker.
What often really confused me was the fact that I didn´t know which part in the mail-flow I was playing when using telnet to manually connect to an SMTP-server during an engagement. Am I acting as SMTP-server or client? Why is it not blocking my attempt to spoof emails at a certain stage?
So I set up a little hMailServer and did some creative googling to get myself started.
Well in fact I had to cheat later on, as hMailServer didn´t support VRFY at all, and so set up another SMTP-server → mercury.
The whole write-up is considering external attacks, and as such you won´t find suggestions for internal hardening measures.
The Simple Mail Transfer Protocol is meant to SEND emails from one system to another.
This can be email-clients like Outlook, mail-servers like Microsoft Exchange, a firewall, etc.
The communication by default is done in plaintext. But nowadays you will most likely see mail-servers switching from plaintext to a secure channel with the help of SSL/TLS.
The default ports are 25, 465 (deprecated) and 587, where 25 is meant to be used for submissions from your e-mail client to the e-mail server and the higher ports for relaying between SMTP-server. More on this can be found here.
A SMTP-server is capable of acting as a client and a server, as it needs to send and receive emails at the same time. Consider a firewall which handles all your emails at “the gate”, outgoing and incoming - both times SMTP is involved.
Some terms used alongside with SMTP are:
Mail User Agent (MUA): This is a (part of a) program connecting to a SMTP-server in order to send an email. Most likely this is your Outlook, Thunderbird, whatever.
Mail Transfer Agent (MTA): The transport service part of a program. They receive and transfer the emails. This might be an Exchange server, an internet facing gateway and so on.
The corresponding RFC5321 is only mentioning these two terms.
However if you start asking the internet about SMTP you will most certain stumble upon Mail Submission Agent (MSA) and Mail Delivery Agent (MDA) and several others.
These are also specific functions of a program involved in the email workflow, and make it possible to describe the process more precisely and granular. A MSA is the part which receives the email from the MUA, and the MDA is the part that will hand over the email to the final receiving MUA. Most likely all these functions will be found in one or two products in your environment, which can take care of all these steps.
So a workflow of an email´s travel from one user to another could look like so:
MUA → MSA → MTA → internet → MTA → MDA → MUA
The terms relay and gateway are clearly defined in the RFC5321 and I will let it do the talking:
A "relay" SMTP
system (usually referred to just as a "relay") receives mail from an
SMTP client and transmits it, without modification to the message
data other than adding trace information, to another SMTP server for
further relaying or for delivery.
A "gateway" SMTP system (usually referred to just as a "gateway")
receives mail from a client system in one transport environment and
transmits it to a server system in another transport environment.
Differences in protocols or message semantics between the transport
environments on either side of a gateway may require that the gateway
system perform transformations to the message that are not permitted
to SMTP relay systems. For the purposes of this specification,
firewalls that rewrite addresses should be considered as gateways,
even if SMTP is used on both sides of them (see RFC 2979 ).
A Sample Configuration
To make things easier to follow along, let´s consider the following scenario of a companie´s email setup:
We have a Microsoft environment with Windows clients and Outlook acting as the MUA.
We have an Exchange server which is just reachable from inside the network. It receives the emails a user wants to send and forwards them if needed.
There also is an internet facing DMZ in which a firewall resides that also acts as a mail-gateway. So the Exchange server sends emails, for receipients outside the domains he is responsible for, to this firewall.
The mail-flow will look like:
Outlook → Exchange → firewall → internet → SMTP-Server of the receiving side → mail-server of the receiving side → Outlook of receiver
Attacking SMTP-Servers - Mail Spoofing
Now to the interesting part.
When you are on an external engagement and you find a device with an open SMTP-port you most likely found a system that takes care of incoming emails from the internet as the first instance - in our case the firewall.
My personal workflow is that I first enumerate the company´s MX records to identify their attack surface regarding SMTP. This can be done by a simple nslookup:
nslookup set type=mx <target>
The result is a list of all systems responsible for incoming mail for that domain.
Next is a nmap scan, to identify open ports:
nmap <target> -p 25,465,587
The output should look something like this:
What I do next is a manual connect to the server with the help of telnet or netcat and check if I can send spoofed emails (from their domain to their domain, as if I would sit inside their network):
First we open a connection to port 25 on the SMTP-server.
We introduce ourselfs as acting on behalf of the company.com domain with an EHLO.
Next specify the senders email-address email@example.com.
Define who is the email for firstname.lastname@example.org.
Specify that we want to send some DATA with the email.
The SUBJECT of our email is set.
We fill the body with some text.
Final terminator for the SMTP communication to show we are done and ready to send is the <.> on a single line.
If you need to connect to a server that only allows encrypted communication, you can use openssl:
openssl s_client -starttls smtp -connect <SMTP-server>:587
At this stage the SMTP-server might react differently from case to case:
- You might not even be able to connect to the server as it performs several checks that you fail to pass:
- Or you might get blocked when saying that you want to send from @company.com as you are not allowed to send from outside the network or a SPF-check is made (more on this later) or authentication is required (more on this later).
- The server might also say: Nice buddy, thanks for the email. I will transfer it.
When the latter happens, this is the point where I first thought: Damn they made a mistake. I was able to send an email on their behalf. Let´s spam them with legit looking phishing mails.
But mostly this turned out to be a wrong assumption. It only tells you that the (in this case) firewall accepted your request in the first instance. If it does other checks afterwards is out of sight for you. Normally the customer would tell me that the email was trapped at the firewall or that is was flagged as somehow malicious inside their Outlook. Both scenarios not putting them at risk.
This also is the point where it becomes clear that the customer needs some kind of authentication. But how exactly and in what cases?
Well, there are several scenarios that might apply here:
1. Someone connects to your SMTP-server and wants to send from an external IP and domain to your domain.
This is the “normal” case that one would assume to happen on a daily basis.
From a customers point of view we want to make sure to check (SPF,DKIM,DMARC) if the sending party is legit to do so. If all checks are passed, the email can be forwarded to the Exchange.
2. Someone connects from an external IP to your SMTP-server and wants to send from your domain.
I would consider this to be at least unusual, as no one from your organisation will directly transfer their emails to the firewall under normal circumstances. The intended way is: Outlook → Exchange and not: Outlook → firewall.
This is where authentication should come into play. Normally Outlook will push your email to the Exchange, and your Exchange will authenticate to the firewall in order to send emails to outside your organisation.
If you reveive external emails, the sending IP and MAIL FROM will be from outside your domain.
So if an external IP wants to send from your domain, and even worse to your domain, you should enforce authentication or otherwise reject the message.
In my testlab a corresponding request will then fail like this:
Authentication itself can be enforced by the use of SMTP-Auth/SMTP. This would allow for a login with PLAIN, LOGIN, CRAM-MD5, SCRAM-SHA-1 or NTLM.
Authentication should always go hand in hand with encrypted communication (SSL/TLS), as credentials should not be transmitted in cleartext over unsecure networks.
More on this topic can be found here: wikipedia
For hMailServer you can granularly set when authtentication is required:
as well as wether to enforce an encrypted communication or not:
3. Someone connects to your SMTP-server and wants to send from an external domain to an external domain.
This would be considered an open mail-relay if allowed and you don´t want that to happen, unless you like yourself to be put on all the blacklists for spammers out there.
This scenario is a type of misconfiguration where everyone would be able to abuse your SMTP-server to send out their SPAM to others around the globe.
What you want to make sure here is the following:
Your SMTP-server should not accept and forward emails from non-local IP addresses to non-local mailboxes by an unauthenticated or unauthorized user.
SPF, DKIM, DMARC
There are three countermeasures that were introdcued to reduce the abuse of emails.
I will just scratch the surface here and try to explain in short what each of them does.
The Sender Policy Framework is checking if the sending system is authorized to send emails for the domain specified in the MAIL FROM field.
To do so, it checks if the sending domain´s DNS records contain a TXT-record with a specific SPF entry:
v=spf1 ip4:184.108.40.206 -all
If the IP part contains the server that sent the email, the receiving end knows that this system was allowed to send emails for the corresponding domain.
To read more on this check: https://postmarkapp.com/blog/explaining-spf
DomainKeys Identified Mail is a security standard designed to make sure that no tampering to an email has happened during the transit from sender to receiver.
This is achieved with the help of public-key cryptography, where a company puts the public-key part inside a DNS-record for their domain and the private-key resides on the system that signs outgoing emails.
These emails will contain a DKIM-signature in their headers, which is created with the help of the private-key.
The receiving end will verify the signature with the help of the DNS-record, and if that passes, the message is considered to be authentic.
To read more on this check: https://postmarkapp.com/guides/dkim
Domain-based Message Authentication, Reporting & Conformance is another standard, which prevents spammers from using your domain to send emails without your permission. It builds on top of SPF and DKIM.
In short DMARC lets you decide what another company should do when receiving emails from your domain that fail to pass the SPF and DKIM checks.
This also is achieved with the help of DNS-records for your domain which might look like so:
_dmarc.company.com TXT v=DMARC1\; p=reject\; pct=100\; rua=mailto:email@example.com\;
This entry will define that 100% = all emails that fail to pass SPF or DKIM should be rejected and a report should be send to firstname.lastname@example.org.
To read more on this check: https://postmarkapp.com/guides/dmarc
Many of the mail-systems nowadays will act on the basis of reputations. This is if a company fails to have implemented SPF, DKIM or DMARC or if it is sitting on a SPAM-blacklist for some reason, it´s reputation will be lowered and communication is less likely to be permitted.
Generally spoken the following points will make your SMTP-servers act in a secure manner (external view):
- allow email from local IP addresses to local mailboxes
- allow email from local IP addresses to non-local mailboxes
- allow email from non-local IP addresses to local mailboxes
- allow email from clients that are authenticated and authorized if none of the three above is true
- make use of SPF, DKIM and DMARC, and don´t allow communication if one of the tests fails
- make use of reputations and only allow trusted sources to communicate with your mail infrastructure
- make use of blacklists
- enforce encrypted communication
Attacking SMTP-Servers - User Enumeration
The enumeration of users is the second type of attack you want to mitigate.
It´s easy for the bad guys to collect a list of email-addresses belonging to your company by social engineering and check their validity with the help of SMTP.
Upon successful validation they can then be used for password-spray attacks and alike - for example against your OWA/EWS, O365, VPN or whatever.
There are at least three methods / commands that will allow for user enumeration:
VRFY: Used to verifiy if a certain user is known to the SMTP-server
EXPN: Used to reveal the actual email-address(es) of an alias
RCPT TO: A needed command to specify to whom the email should be send
You can check if the commands are available with the HELP command (if available).
VRFY and EXPN both work the same way. You enter the command alongside with the account, name, alias or email-address you want to check. The response will either give you a 250/251 telling you that the account exists or expand the alias, or give you a 550, informing you about an invalid account.
The good news is, that you can disable VRFY and EXPN without a problem, and you should probably do so.
The server´s response should then look like so:
In contrast RCPT TO is a needed must for the whole thing to work.
Fun fact: When I did the research for this blog-post, the very first google entry regarding SMTP and pentesting suggested to turn off RCPT TO. If that would be possible, you would render your SMTP-server useless.
However you can make it harder for attackers to enumerate your users by the following means:
- Implementation of a catch-all-address / catch-all-rule / catch-all-server
This will reply to every request with a 250 Receipient OK. This might tell an attacker that you use a catch-all variant, but it won´t reveal users that actually exist. At a later step, not visible to the attacker, you can decide about what to do with emails send to unknown addresses.
- Limit maximum number of failed RCPT TO attempts
If possible and supported, add a rule that kicks off connections, if too many failed RCPT TO attempts have been made by the same originating IP.
If configured unsafe, SMTP-servers can put your company at a high risk. You neither want external parties to send emails from your domain to your domain without authentication, nor do you want your SMTP-server to act as an open mail-relay.
Make use of the security mechanisms that are available to protect your environment as much as possible.
From an attackers point of view it´s always useful to check for these low hanging fruits to get an initial foothold by spoofed phishing emails or at least do some recon on valid users and email-addresses. These might come in handy for further attacks like password-spraying.
So that´s it for now.
I hope hope you liked this blog-post and were able to take away at least something.
Happy hacking fellas.