Could we help you? Please click the banners. We are young and desperately need the money
Email-based phishing attacks are becoming increasingly sophisticated, with attackers often impersonating legitimate domains to deceive recipients. One common technique is using a recipient's domain name within the sender's email address or display name while sending from a different domain. This article shows you how to implement a custom SpamAssassin plugin that detects such domain spoofing attempts.
Domain spoofing in emails typically follows these patterns:
The plugin implements an intelligent detection mechanism that:
Create a new file named check_domain_spoofing.pm
in your SpamAssassin plugins directory (typically /etc/spamassassin/
or /usr/share/spamassassin/
) with the following content:
package Mail::SpamAssassin::Plugin::CheckDomainSpoofing;
use strict;
use warnings;
use Mail::SpamAssassin::Plugin;
use vars qw(@ISA);
@ISA = qw(Mail::SpamAssassin::Plugin);
sub new {
my ($class, $mailsa) = @_;
$class = ref($class) || $class;
my $self = $class->SUPER::new($mailsa);
bless ($self, $class);
$self->register_eval_rule('check_domain_spoofing');
return $self;
}
sub check_domain_spoofing {
my ($self, $pms) = @_;
# Get all recipient domains from To: and Cc: headers
my @recipient_addresses;
foreach my $header ('To', 'Cc') {
my @addresses = $pms->get("${header}:addr");
foreach my $addr (@addresses) {
next unless $addr;
push @recipient_addresses, lc($addr);
}
}
return 0 unless @recipient_addresses;
# Get both the From address and display name
my $from_addr = lc($pms->get('From:addr'));
my $from_name = lc($pms->get('From:name'));
return 0 unless ($from_addr || $from_name);
foreach my $recipient_addr (@recipient_addresses) {
# Extract domain and TLD from recipient address
next unless $recipient_addr =~ /\@(?:.*?\.)?([^.]+)\.([^.]+)$/;
my ($recipient_domain, $recipient_tld) = ($1, $2);
# Check if recipient's domain appears in FROM local-part or display name
next unless (
($from_addr && $from_addr =~ /^[^@]*\Q$recipient_domain\E[^@]*@/i) ||
($from_name && $from_name =~ /\Q$recipient_domain\E/i)
);
# Check if FROM address's domain matches recipient's domain
# If it does match, this is legitimate (same-domain communication)
next if $from_addr =~ /\@(?:.*?\.)?$recipient_domain\.$recipient_tld$/i;
# If we get here, we found a case where:
# 1. Recipient's domain appears in FROM local-part
# 2. BUT FROM address is from a different domain
return 1;
}
return 0;
}
1;
Add the following configuration to your local.cf
file:
loadplugin Mail::SpamAssassin::Plugin::CheckDomainSpoofing check_domain_spoofing.pm
### Detect domain spoofing attempts where scammers use legitimate domain names in their FROM addresses
### This rule checks if either the sender's display name OR email address contains a recipient's domain name
### but sends from a different domain.
###
### Examples that would be marked as SPAM:
### FROM: "ACME Corp Support" <support@phishing.com> TO: employee@acme.com -> SPAM (contains "acme" in display name)
### FROM: John Smith <john.smith.acme@gmail.com> TO: employee@acme.com -> SPAM (contains "acme" in email)
### FROM: "IT Team - acme.com" <it@malicious.net> TO: employee@acme.com -> SPAM (contains "acme" in display name)
###
### Examples that would pass (legitimate traffic):
### FROM: "John Smith" <john.smith@acme.com> TO: employee@acme.com -> OK (same domain)
### FROM: Newsletter <news@mail.acme.com> TO: employee@acme.com -> OK (subdomain)
### FROM: "Support Team" <support@vendor.com> TO: employee@acme.com -> OK (no "acme" anywhere)
header DOMAIN_SPOOFING eval:check_domain_spoofing()
describe DOMAIN_SPOOFING Sender impersonates recipient domain
score DOMAIN_SPOOFING 5.0
The plugin includes several mechanisms to prevent false positives:
Feature | This Plugin | SPF | DMARC |
---|---|---|---|
Detects Display Name Spoofing | Yes | No | No |
Catches Freemailer Abuse | Yes | No | Limited |
Easy to Implement | Yes | No | No |
Requires DNS Configuration | No | Yes | Yes |
sudo cp check_domain_spoofing.pm /etc/spamassassin/
sudo nano /etc/spamassassin/local.cf
spamassassin --lint
sudo systemctl restart spamassassin
spamassassin -D --test-mode < test_email.txt | grep DOMAIN_SPOOFING
The recommended score for this rule depends on your environment, where in most cases Emails with spam scores > 5.0 are considered to be spam:
This SpamAssassin plugin provides an effective defense against domain spoofing attacks by detecting attempts to impersonate legitimate domains in email communications. While it works well alongside existing email authentication methods like SPF, DKIM, and DMARC, it adds an extra layer of protection by catching spoofing attempts that these protocols might miss, particularly in the display name and local part of email addresses.
The plugin is especially effective against social engineering attacks where scammers try to establish trust by including the recipient's domain name in their sender information. By implementing this plugin, you can better protect your users from these increasingly common phishing attempts.