Pro / dkim-exchange

DKIM Signing Agent for Microsoft Exchange Server
Other
402 stars 139 forks source link

External mails with spoofed email also signed with DKIM #116

Open avoidik opened 8 years ago

avoidik commented 8 years ago

I don't know if this problem related to dkim-exchange, but emails from external server with spoofed sender got also signed.

Goto https://www.wormly.com/test_smtp_server and send sample email with fake sender with own domain name (from fake@mydomain.com to my_valid@mydomain.com). Check signature, it's signed.

Nice way to break in with spam or infected attachments.

Pro commented 8 years ago

Jep, that may be a problem. A solution to this would be to check where the mail comes from, i.e. have a list with trusted sender IPs. For that it is necessary to add an additional field in the Configurator, since mails may also come from other internal or even external trusted servers and should be signed.

avoidik commented 8 years ago

I think it's question about directions, DKIM agent must sign only outbound emails, not inbound.

Pro commented 8 years ago

The question is if it is possible to get this information within the source code. I need to investigate that further...

avoidik commented 8 years ago

In RoutingAgent we can use mailItem.Message.RootPart.Headers.FindFirst("Received"); to resolve IP and compare with permitted signers. In our case it will be our external IP or it can be another itemlist in GUI as you said above.

Pro commented 8 years ago

@AlexLaroche can you look at this and see if there's a solution? (add it to the new mime_kit branch)

AlexLaroche commented 8 years ago

@avoidik : Can you draw your Exchange architecture (Edge and Hub server, spam filtring, etc.) and what your email traffic is configure to do (who reveice from external, from internal, relay!?, who send from internal, etc.)? I don't need private information, just the architecture to understand how your environnement is setup.

avoidik commented 8 years ago

My environment is Exchange2010 SP3 CU11. Check out idea in pull request.

gogglespisano commented 8 years ago

Should the better fix be to only sign outgoing emails and ignore incoming emails regardless of sender?

avoidik commented 8 years ago

AFAIK it's impossible in RoutingAgent, need to change superclass to something else and rewrite whole agent.

AlexLaroche commented 8 years ago

The real problem isn't the incoming or outgoing emails.

A email server just forward email if it isn't the final destination.

The problem is that permit sender isn't correctly manage for your domain.

Restrict who can send email from your domain name in your organization to your Exchange server/email server (use AUTH).

It's also a good idea to activate SPF.

Check the follow example:

ABC don't want to expose their exchange on the Internet.

XYZ offer email service for their clients.

ABC contact XYZ and ask them if they can fronted Internet for them so al their email traffic will be send from their server.

XYZ accept in exchange of some money.

ABC forward their traffic to XYZ and XYZ will send the traffic to destination.

When XYZ will receive traffic for ABC, XYZ will send the traffic to ABC.

If XYZ receive traffic from traffic HYZ (using domain ABC), XYZ should check and see that only ABC and XYZ can send traffic from ABC domain.

Without DKIM Agent or not, you currently have a infrastructure problem.

The problem isn't the agent.

AlexLaroche commented 8 years ago

Powershell :

# Don't receive from anonymous if it's an authoritative domain
Get-ReceiveConnector “My Internet ReceiveConnector” | Get-ADPermission -user “NT AUTHORITY\Anonymous Logon” | where {$_.ExtendedRights -like “ms-exch-smtp-accept-authoritative-domain-sender”} | Remove-ADPermission

If you want to use external email service that you use your domain, they will have to implement authentificate email relay : http://geekswithblogs.net/ksellenrode/archive/2014/05/03/156170.aspx

Pro commented 8 years ago

@AlexLaroche I think what avoidik meant is that the DkimSigner Agent is checking every mail, this means outgoing and incoming (since both are sent through SMTP). (Correct me if I'm wrong) If someone sends a mail to my exchange server with a spoofed (=wrong) From address which matches the DKIM Signer configuration, it gets signed, but it shouldn't.

AlexLaroche commented 8 years ago

@Pro : The DKIM agent should sign ALL emails that the routing service receive. The routing service use Outgoing connectors. His job is to take the message and send it to the destination. Nothing more!

Exchange is base on three main process (SmtpReceive, Routing, Delivery).

The main problem in the case of avoidik is that his server receive a email from a untrusted source for a authoritative domain (able to be trusted, owned domain) and he accept the email from any servers in the Internet!! Exchange receive email from SmtpReceive (Incoming Connectors), the mailbox isn't in the current server so Exchange take the email and pass it to Routing process (Outgoing connectors). The Routing process take is message (sign the email because it send the email and match the domain to sign) and send it to the destination server (where the mailbox is store).

You have to see Exchange has a trusted subsystem. You have to validate at the source (Incoming connectors configuration) if the sender is spoofed, not in the DKIM signer.

Pro commented 8 years ago

@AlexLaroche I think what @avoidik means here is the following scenario:

EHLO example.org
MAIL FROM: <name@example.org>
RCPT TO: <user@example.com>
DATA
SUBJECT: Test Mail
.

This is a standard mail delivery from external mail servers to your exchange server.

Now here comes the interesting part:
This test email is also routed through the DKIM signer, this means it also tries to sign incoming emails. So if you modify the commands above to use an existing user:

MAIL FROM: <user@example.com>
RCPT TO: <user@example.com>

The DKIM signer also signs the email because it thinks that it was received internally. (Open relay is of course disabled) Unforunately the Recipient Header field contains the server's ip as the first field and thus this can't be used to distinguish between outgoing and incoming.

We need to investigate how this can be avoided. Maybe evaluate all the Recipient Header fields instead of just the first one (as proposed in https://github.com/Pro/dkim-exchange/pull/117)?

I got those results within my test environment.

Pro commented 8 years ago

See also: https://msdn.microsoft.com/en-us/library/office/dd877035%28v=exchg.150%29.aspx

Pro commented 8 years ago

I think the correct field to check is the MailItem.Recipients[0].RecipientCategory (https://msdn.microsoft.com/en-us/library/microsoft.exchange.data.transport.mailitem.recipients.aspx) For the above telnet SMTP delivery this has the value Incoming. For an outgoing mail it has InDifferentOrganization See https://msdn.microsoft.com/en-us/library/microsoft.exchange.data.transport.recipientcategory%28v=exchg.150%29.aspx

Or we can evaluate the X-MS-Exchange-Organization-MessageDirectionality header field as mentioned here: https://social.msdn.microsoft.com/Forums/office/en-US/9387e62a-76d7-4340-b9cc-f87ffcfab8b1/how-to-detect-the-message-source-in-an-exchange-server-2013-transport-agent-for-getting-the-sending?forum=exchangesvrdevelopment&prof=required

Checking the presense of the message header "X-MS-Exchange-Organization-MessageDirectionality" solves it.
It's set to "Originating" for e.g. outgoing OWA message.

For incoming messages via SMTP it's not yet set in the EndOfData event.
And later on in the routing events it's set to "Incoming".```

Here we need to find out which values are set for all the different use cases how someone can use Exchange to send messages (e.g. Outlook, OWA, Thunderbird over SMTP, Relay/SmartHost)
AlexLaroche commented 8 years ago

@Pro: Just remove the right (access) to receive email from anonymous to your external connector for your authoritative domains (domains, you have configure in exchange).

It's the job of the agent to do that. Give a try to my solution and you will see that your example is managed.

# Don't receive from anonymous if it's an authoritative domain
Get-ReceiveConnector “My Internet ReceiveConnector” | Get-ADPermission -user “NT AUTHORITY\Anonymous Logon” | where {$_.ExtendedRights -like “ms-exch-smtp-accept-authoritative-domain-sender”} | Remove-ADPermission
ablanken commented 8 years ago

@AlexLaroche That solution will not work for people using external email filtering services (Gapps, Exchange Online Protection etc) combined with an increasing amount of online services that send email from your authoritative domains.

avoidik commented 8 years ago

So we need bluelist then. Something like this was proposed in https://github.com/Pro/dkim-exchange/pull/117

AlexLaroche commented 8 years ago

@ablanken : Your concern can be address in the follow ways : Create a account in your Exchange environnement and grant appropriate rights.

For external email filtering services (Gapps, Exchange Online Protection, etc)

Get-ReceiveConnector –Identity “My Internet ReceiveConnector” | Add-ADPermission -User “<Domain>\<Account>” -ExtendedRights “ms-exch-smtp-accept-any-Recipient”

If your really trust the sender, You could even bypass Exchange Anti-Spam system

Get-ReceiveConnector "My Internet ReceiveConnector" | Add-ADPermission -user "<Domain>\<Account>" -ExtendedRights "ms-Exch-Bypass-Anti-Spam"

For online services that send email from your authoritative domains

Get-ReceiveConnector “My Internet ReceiveConnector” | Get-ADPermission -user “NT AUTHORITY\Authenticated Users” | where {$_.ExtendedRights -like “ms-exch-smtp-accept-authoritative-domain-sender”}

If you really need anonymous receive connector, for security reasons, create a new receive connector and please open it access only point to point (via your firewall).

Reference for special Exchange Rights : https://technet.microsoft.com/en-us/library/jj673053(v=exchg.150).aspx

ghost commented 8 years ago

Why not refactor this as a SmtpReceiveAgent instead of RoutingAgent.. since this applies to the message whenever its being sent out via SMTP is when this should be done, not when in routing. since a message can get routed multiple times its easy to get multiple signs, which I had problems with.

Also it's easy to tell if the message is internal -> external or not using a combination of rcptArgs.SmtpSession.IsExternalConnection (takes into account authorized proxies, as well as localhost, and other exchange servers in the cluster) and checking to see if the source domain is in the signing list. This would prevent external servers from sending inbound with faked source and getting signed.

Pro commented 8 years ago

This sounds reasonable, but I'm currently not up to date on the capabilities/differences between the RoutingAgent and SmtpRecieveAgent. Also currently I don't have time to investigate that further. If you want, you can check if it is possible to use the SmtpReceiveAgent and modify the Source to create a Pull Request.

p-try commented 2 years ago

I would like to raise awareness of this issue. Messages with spoofed sender addresses are still signed so bogus messages bearing a sender address from the authoritative domain cannot be filtered out. Unfortunately, removing the right "ms-exch-smtp-accept-authoritative-domain-sender" from the receive connector does not work as suggested because this right is only evaluated for HubTransport connectors. However, the default receive connector on port 25 is a FrontendTransport. See https://docs.microsoft.com/en-us/answers/questions/203616/ms-exch-smtp-accept-authoritative-domain-sender-de.html

mikekay1 commented 10 months ago

I would like to raise awareness of this issue. Messages with spoofed sender addresses are still signed so bogus messages bearing a sender address from the authoritative domain cannot be filtered out. Unfortunately, removing the right "ms-exch-smtp-accept-authoritative-domain-sender" from the receive connector does not work as suggested because this right is only evaluated for HubTransport connectors. However, the default receive connector on port 25 is a FrontendTransport. See https://docs.microsoft.com/en-us/answers/questions/203616/ms-exch-smtp-accept-authoritative-domain-sender-de.html

Did you find an answer to this? I am facing the exact same issue and it makes no sense how something with a spoofed domain is getting signed with dkim, and regardless should dmarc fail the email because spf didnt align? Exchange is garbage and pushing its cloud products to try and get us to ditch on prem... I will not pay for EOP on top of exchange licenses...

p-try commented 10 months ago

Did you find an answer to this? I am facing the exact same issue and it makes no sense how something with a spoofed domain is getting signed with dkim, and regardless should dmarc fail the email because spf didnt align? Exchange is garbage and pushing its cloud products to try and get us to ditch on prem... I will not pay for EOP on top of exchange licenses...

Unfortunately not. We are currently not using the software due to this issue. I am considering fixing this myself but I couldn't find the time so far.

mikekay1 commented 10 months ago

Its the only open source aoftware available it sucks because others literally want me to put a postfix smarthost inbetween essentially running two mail server because microsoft cant incorporate basic RFC features into a 2019 product?

Honestly might make my mailboxes read only and finally switch over to a VM with something from this century that support SSO.

Are you using any other software? There is email architect and Netal, any experience with those?

avoidik commented 10 months ago

You could try to revive #117 as this is the only viable workaround available to the moment, even though it was closed. Cheers.

mikekay1 commented 10 months ago

117 looks like it works but not if they telnet into esmtp and send email that way which still is better than nothing, so thank you for the suggestion. I still dont understand how anonymous users are able to submit mail through port 25, like isnt it basically an open relay at that point? Or no because it only works to email inwards?