Disclaimer: This article is not an “Email Spoofing 101”. Spoofing examples are presented only for testing and prevention purposes.
Ensuring email security might be one of the most important and most difficult tasks an administrator must face. Every day, servers process thousands of emails and controlling such a big mail flow is not easy. No wonder hackers focus on this channel when they plan attacks. They use various tricks to make users think that opening a suspicious attachment is a good idea.
One of the tricks they use is email spoofing.
What is email spoofing?
Email spoofing is a very popular attack method. The sender modifies message headers so that emails appear as sent from someone else. Hackers use it, for example, to impersonate employees of a company to obtain login credentials, personal data, or other confidential information. Two most common ways to protect your organization from external spoofing attacks are:
- An SPF record – a list of IP addresses which are authorized to send emails from a domain.
- DKIM check – an email authentication method. It enables you to sign and verify email messages using public and private keys. The public keys, published in the DNS records are used to verify if the message comes from the original sender. You cannot configure it on the Exchange Server natively – you require a plugin for SMTP gateway.
Both ways give good results when fighting with external spoofing. The problem starts when we come across internal spoofing when one employee tries to impersonate a colleague. It might be a joke, or to achieve some benefits – either way, it can sabotage a company in a number of ways:
- Cause chaos,
- Induce material damage,
- Harm data integrity,
- Damage the company reputation.
What is worse, fighting internal spoofing attempts requires a slightly different approach. I will now present how to prevent internal email spoofing in an Exchange organization. But first, a quick specification of the test environment:
Test environment
For presentation and test purposes I will use the following machines:
– Windows Server 2012 as a Domain Controller. The domain name is domain128.lab , IP 192.168.23.1
– Windows Server 2012 R2 with Exchange 2016 CU3, IP 192.168.23.2, 192.168.170.79
– Windows 10 with Outlook 2013, IP 192.168.23.3
– Windows 7, IP 192.168.23.4
Now for the proper part. I will show how email spoofing attacks are performed and how to prevent them:
Internal email spoofing
First, let us see how an employee can masquerade as another user when sending an email. A single PowerShell cmdlet is enough to achieve that. In the example below, [email protected] impersonates [email protected] and sends an email to [email protected]
The cmdlet used by user1 is as follows:
Send-MailMessage –SmtpServer 192.168.23.2 –To [email protected] –From [email protected] –Subject “It`s me user3” –Body “Send me your report”
Of course, such email should not do any harm. If the user2 replies to the message, the email will go to user3, not the attacker. The problem is that after some modifications, Send-MailMessage can send HTML emails with malicious links or attach an infected file. I will not go through examples of how spoofing can be used to harm an organization, but believe me; there are many.
The same trick can be achieved by using the Telnet Client. The Telnet Client is not installed by default, but you can go to Control Panel > Programs > Turn Windows features on or off and select Telnet Client there to turn it on. To test internal email spoofing, run cmd.exe and connect to your server on port 25 by inserting:
Telnet 192.168.23.2 25
Just remember to substitute the IP address with yours.
Next, using SMTP commands, you can send an email:
HELO domain128.lab (connects to your domain)
MAIL FROM: [email protected] (address of the user you want to impersonate)
RCPT TO: [email protected] (your victim’s address)
DATA: it enables you to specify subject and body of your email. Enter a full stop (.) in a new line to finish data input.
Both methods end with the same result:
For a more realistic situation, a similar attack deployed in a different environment looks like that:
As you can see, the email does not differ from any other message, sent by normal means. It is very easy for the recipient to fall for this trick. As an administrator, you can detect such action in Exchange logs, but in a larger organization with a lot of users and intensive mail flow, it will be troublesome, to say the least. Not to mention that the harm can be done before such an attempt is detected. So why Exchange permits such behavior? And how to block it?
In a default Exchange deployment, a Receive connector is created. Default Frontend (your server’s name) is configured so that it:
- receives from all IP addresses
- Uses the default SMTP port 25 to receive emails
- Enables emails from anonymous users
This last point is what enables internal users to abuse the mailing system. Unfortunately, turning the permissions for anonymous users off would also block receiving emails from external email addresses. Well, I do not know in what environment that would be a reasonable option.
How to prevent internal email spoofing
There are probably many third party solutions which fight this threat, but in this article, I will only present how to rule out spoofing inside an organization using native Exchange mechanisms. There are two methods I will demonstrate:
- How to block spoofing attempts using SPF record,
- How to prevent internal spoofing with a dedicated Receive connector
Using SPF record
As I have already mentioned while describing external attacks, one of the most popular (and effective) weapons against spoofing attempts is using the SPF record. See the syntax of an SPF record, below:
V=spf1 ip4:your_server’s IP –all
To put it simply, SPF records reside in DNS zone file. They specify IP addresses of servers which are allowed to send emails from a certain domain (more on creating SPF record). The mechanism can be used to secure internal correspondence analogically to the way it is normally used for external communication. For this method to work for internal email spoofing, you will need to configure three elements:
- An SPF record in local DNS,
- Antispam functionality in Exchange Server,
- A Sender ID agent.
Before I walk you through the configuration process, I will talk about its major drawback. To block internal email spoofing completely using this method, you have to include all IP addresses which are allowed to send emails in your network (this includes printers, applications, and other web objects). This is not the most convenient solution if you have a vast network with loads of various devices. But if you do not have an overwhelming infrastructure and you know it like the back of your hand, the solution should work well.
Step by step walkthrough
- First, you should create the txt record on your DNS server in the local domain. In my case, the record will look like this:
v=spf1 ip4:192.168.23.2 ip4:192.168.170.79 ip4:192.168.169.51 –all
192.168.23.2 and 192.168.170.79 are the IP addresses of my Exchange Server, while 192.168.169.51 is the IP address of my web printer in another subnetwork. The printer sends emails to Exchange.
- The next step is the installation of Exchange Antispam Agent. You can use PowerShell to do that. The cmdlet is:
& $env:ExchangeInstallPath\Scripts\Install-AntiSpamAgents.ps1
Successful installation should look like that:
- Now for the changes to apply, restart your MSExchangeTransport service:
Restart-Service MSExchangeTransport
- Provide all Exchange Servers’ IP addresses:
Set-TransportConfig –InternalSMTPServers
I have to provide two addresses because my Exchange Server has two network interfaces.
- We are almost done. Now, you have to configure a rule which rejects emails from addresses which are not included in your SPF record. The PowerShell cmdlet is:
Set-SenderIdConfig –SpoofedDomainAction Reject
- All that is left is to test if the current configuration successfully blocks internal spoofing attempts, as it should. I will use the same cmdlet I presented at the beginning of the article. Instead of sending an email, the attacker should get the following error:
As you can see, the Exchange server blocks the attempt and displays error 5.7.1 “Sender ID <PRA> Not Permitted.
The effect will remain the same even if the user enters their own mailbox in the –From attribute:
Finally, let us check what happens if I try to masquerade as another user on a machine with IP address 192.168.169.51 (the one I added to the local SPF record before):
The mail went through without a problem:
This example shows another drawback of the SPF record method. Because the authentication bases on the sender’s IP, the wrong configuration will not guarantee that your company is completely guarded against internal spoofing.
Implementing this method does not influence sending emails from email clients (Outlook, OWA or ActiveSync) because they use RPC or MAPI over HTTP through a different port (443 or 80).
Using a dedicated Receive connector
The second method is creating an additional Receive connector on the port 25. The connector controls the local network and lets through only emails from domain users. This approach uses a different authorization method. Instead of using IPs, it uses domain credentials (login and password). The change of the authorization method generates one problem – all internal Exchange connections have to be authorized. In other words, every web device and application which sends emails to Exchange requires a domain account (or, at least, they can have one, common account).
As I have mentioned before, the connector will be set for the TCP port 25. But, as you may know, there is already a Receive connector, which accepts anonymous connections from SMTP servers on port 25. So how can this connector coexist with the one you are about to create? And how does Exchange know which one to choose? Exchange Server is quite intelligent when it comes to this. The server will always choose the more precise connector for each connection. The Receive connector I configure is defined for LAN networks, while the default one applies to all connections. Hence, for internal SMTP connections, Exchange will always choose the new connector, specified for LAN.
Step by step walkthrough
The second method, apart from being more secure, is easier to implement. That is because it requires only to create a new Receive connector. You can use a nice PowerShell cmdlet for that. I will use Internal Client SMTP name for the connector so that I can identify it easily later. Remember, the IP ranges are personalized for my environment:
New-ReceiveConnector –Name ”Internal Client SMTP” –TransportRole FrontendTransport –Usage Custom –Bindings 0.0.0.0:25 –RemoteIPRanges 192.168.23.0/24,192.168.170.0/24 –AuthMechanism TLS,Integrated –PermissionGroups ExchangeUsers
I should also be able to create it in Exchange Administration Center > Mail Flow > Receive Connectors > New:
The settings are analogical to those used in the cmdlet above. The connector should be internal, and the role should be set to Frontend Transport… Unfortunately, the default Role is Hub Transport, and it seems I cannot change it to the option I need. Let us go on and see what happens, anyway.
The next page is very important – that is where you have to specify all LAN networks you have in your organization. In my case, it is 192.168.23.0/24 and 192.168.170.0/24.
That is where Exchange throws an error.
The values that you specified for the Bindings and RemoteIPRanges parameters conflict with the settings on Receive connector “ENV128-E2016\Default Frontend ENV128-E2016”. Receive connectors assigned to different Transport roles on a single server must listen on unique local IP address & port bindings.
It seems that Exchange does not like having two connectors with different Transport roles listening to the same port. But the two roles are different only because an option was grayed out… Which is peculiar, considering the fact that a single cmdlet did not throw any errors. You can check if you encounter the same bug, but my advice is to just go with the PowerShell.
The connector (regardless of how you create it) should appear on the list:
Now for the testing. user1 will try to send a message to [email protected] as [email protected].
The PowerShell command already used a couple of times in this article does not send an email this time. The error code is different from the one which appeared using the previous method: 5.7.60 SMTP; Client does not have permission to send as this sender.
Ok, what if the user tries the same trick after providing his/her credentials?
Good, still no luck. But when the same user stops trying to appear as someone else:
The cmdlet does its job. The today’s victim, [email protected] can read the message along with its original sender:
Internal spoofing attempts are also blocked if the malicious user tries using telnet:
Summary
As an Exchange Server administrator, you have to be aware that the default Exchange deployment is not enough to protect your users from malicious emails. Fortunately, you can use this guide to prevent internal email spoofing once and for all. Both methods is based on native Exchange mechanisms, all you need is a little effort.
When using a dedicated Receive connector, every web device and application which sends emails to Exchange requires a domain account. Creating such an account is easy, but how to prevent this account from appearing in the global address list?
You can go to Active Directory Users and Computers, open the account properties and on the general tab choose Hide from Exchange address lists.
I liked this article since I have a same issue with my organization. I noticed that Powershell is a requirement for above solution. One question to all: If the mail server is not an Exchange Server, what would be the possible solution?
It depends on what’s the email server and what are the tools at the admin’s disposal. Can you configure receive connectors or SPF records in a similar manner?
Powershell is only a means to create the right configuration here.
The real issue with display names is that they are essentially meaningless– yet people treat them as gospel. There are no rules for display names, and therefore, they cannot be validated, because there are no rules against which to validate them. Your display name can be anything you want it to be. Spoofing a display name requires nothing more than an ordinary e-mail client such as Outlook with an account set up manually with whatever display name you like. If you want to be “Superman,” just type that in the display name box. No one can prevent you from doing that apart from DC Comics’ lawyers– but that is not a technical issue, it’s a legal issue.
True, but relying on display names is another problem. People who know about the potential meaninglessness of display names often rely on the the email address, instead. And spoofing lets you tamper with that, too.
It all comes down to reducing risks however we can.
Jesse B:
Your are missunderstanding something
If You are connecting from a Client/Mail Client through the Client FrontEnd Connector (587) using authentication (WITH ECHO and TSL configuration ok), you dont need to add extended rights to that connector. You dont need to add Accept-any-sender (Accept-Any-Recipient is added by default). You are right, the connection flow is done from Client FrontEnd Connector (FrondEnd Transport) to Client proxy Connector (Hub transport).
When you read in logs that Client does not have permissions to send as this sender (550 5.7.60) in this case, is for an extended Right (missing) in the Proxy Client Connector
Check: Rights:
Get-ADPermission -Identity “Client Proxy *” | where {($_.Deny -eq $false) -and ($_.IsInherited -eq $false)} | Format-Table User,ExtendedRights
Then add: ms-exch-smtp-accept-authoritative-domain-sender
Get-ReceiveConnector -Identity “Client Proxy *” | Add-ADPermission -User “Authenticated Users” -ExtendedRights “ms-exch-smtp-accept-authoritative-domain-sender”
One other method you can use if you have a spam filter or other smart host that accepts mail from outside. Create a new connector just for relaying email and lock it down by IP address. We called ours “Allowed to Relay”. You can put IP addresses of printers, servers, and other devices that want to send email through Exchange, and they will be able to. These IP addresses would also include the IP of your smarthost as well.
Then, you can simply un-check the “Anonymous” checkbox on your “Default Frontend ” connector. When you go to spoof an email you will get a “530 5.7.1 Client was not authenticated” message when you try using telnet.
Hi Anthony,
Thanks for the idea!
Hi.
Excellent document
It works very well internally within my LAN but if the fraud attempt is made from outside (internet) through telnet the problem persists.
How can I make it work also from the outside and can not make me fraud from telnet?
Thank you very much.
Regards.
Hi Miguel,
Preventing spoofing from the outside is handled by using by DKIM / SPF methods, as mentioned in the beginning of the article.
Great article, exactly what I was looking for!
Now I’m trying to figure out how to create a receive connector that allows internal email spoofing from a specified list of addresses, but requires that connections be AD-authenticated.
I created such a frontend receive connector and added the necessary permissions (ie. Add-ADPermission -User “contoso\Relay” -ExtendedRights ms-Exch-SMTP-Submit,ms-Exch-SMTP-Accept-Any-Recipient,ms-Exch-SMTP-Accept-Any-Sender,ms-Exch-SMTP-Accept-Authoritative-Domain-Sender,ms-Exch-Accept-Headers-Routing). However, while the logs do show the messages being passed from the frontend connector to the ‘Client Proxy EX2016’ connector, the message is rejected by the latter with “Client does not have permissions to send as this sender.”
Only when I also add the permissions to the Client Proxy connector do the messages go through. But doing so makes the frontend connector (which limits by IP) moot, as any sender address can send to the Client Proxy directly (on port 465), as long as they’re authenticating with contoso\Relay.
Is it not possible to achieve what I’m trying to do (allows internal email spoofing from specified IP’s and require AD authentication)?
To be honest, I’m not sure if such granularity is possible. I’ll test it when I find some free time and let you know if I managed to figure it out.
Our IT department decided to implement a huge highlighted message for all external emails received. This highlighted paragraph overpowers the email threads and is added every time to the thread. Is there a recommendation for our IT department to re-evaluate this workaround from notifying us that that email is external?
Adding an overpowering message each time to the thread seems a bit too much. You could add exceptions to the rule, so that such message is added only once. You could also follow instructions from the article below to see how to add a warning message to messages from external recipients AND automatically delete it from replies. This way, external recipients will not get those warning messages. How to add a warning message to emails originating from outside of your organization?
Great Document. Thank you for your sharing man. Its saved my life… God bless you.
Im assuming “internal” means inside my domain, why would i not want to allow someone inside my domain to be able to spoof someone else inside my domain?
It is very useful to allow “internal” spoofing for applications to send email on behalf of our domain users to other of our domain users. Cant see any internal threat that would be worth losing this.
You wouldn’t like to get an email from CEO, stating “You’re fired”, would you? Even if you don’t believe it, would you ignore it? Or how about “drop by my Office in a few minutes”? In some companies that sort of thing is not limited to April Fools’ Day. “Sending on behalf” is another story – in those cases, you can immediately see that the message is sent by someone (or something) else. Internal email spoofing does not require any impersonation rights and is hard to trace – that is why some organizations might want to prevent it.
Hello
Is it possible reject invalid helo in exchange ?
Could you explain what you mean by invalid helo? As far as I know, when you type invalid HELO command, you will not connect to anything.
What I don’t understand is how you can send a spoofed internal email this way without Exchange blocking the sender as not having permissions to ‘Send As’ that user. Why does the system not detect this basic security breach?
Are you able to provide support for evaluating the current smtp send/receive connectors of a global 2013 deployment?
Do you mean you would like me to help with configuration of the SMTP connectors so that they do not allow internal spoofing? I think it would be best and safest if you follow the steps from the article. Then, you should be able to evaluate your connectors’ settings by trying the telnet spoofing method yourself.
If you encounter problems at any part of the configuration, please specify at which point and I will try to help.
If you have an SMTP Gateway can you simply amend the Default FrontEnd connector to only accept from specific Remote IP Addresses (SMTP Gateway, and any internal SMTP devices). You can leave Anonymous checked, but shouldn’t be able to masquerade as another user?
Great article.just need to know how can you prohibit someone outside your network to telnet port 25 and act as your user ?
I mean on exchange level.
Thank you
As I state at the beginning of the article, you can block all external spoofing attempts by configuring the SPF record or deploying the DKIM email authentication.
Can you prevent on the server side in Exchange an internal user send out multiple messages to other internal e-mail boxes in an automated fashion? Looks like Mail Gateways protect only mails in-out and out-in into the domain but not in-in! Any recommendation to monitor/restrict internal to internal mail flow (flooding etc?)?