Phishing for Big Money Wire Transfers is Still Alive and Well (or: For Want of Good Punctuation, all was Lost)

Published: 2017-03-02
Last Updated: 2017-03-02 14:11:35 UTC
by Rob VandenBrink (Version: 1)
5 comment(s)

I recently had a client get an interesting phishing message.   They had received a fake message from their CEO to their Controller - a "start the conversation" email to end up with a wire transfer.  This sort of email is not common, but is frequent enough in Sr Management circles, especially if you are in the middle of merger or acquisition discussions with another company.

Some technical warning signs in that note were:

  • While the "From" field in Outlook showed the CEO's email, the "Reply-To:" field was not to the organisation's domain at all, it was to a bogus inbox at "".  
  • The message ID and the path showed that the original mail exchanger was at  (again, not the organisation).

So the discussion quickly moved from "I'm glad our execs came to us, we really dodged a bullet there" to "just how did this get in the door past our spam filter anyway?"

This is where things got interesting.  Their SPAM filter does use the SPF (Sender Policy Framework) DNS TXT record, and a quick check on the SPF indicated that things looked in order there.
However, after a second look, the problem jumped right out.  A properly formed SPF will end with a "-", which essentially means "mail senders in this SPF record are valid for this domain, and no others".  However, their SPF had a typo - their record ended in a "~" instead.  What the tilde character means to this spam filter is "the mail senders in this SPF record are valid for this domain, but YOLO, so is any other mail sender".

From the RFC (RFC7208), the ~ means "softfail", "A "softfail" result is a weak statement by the publishing ADMD that the host is probably not authorized".  More detail appears later in the RFC:
"A "softfail" result ought to be treated as somewhere between "fail" and "neutral"/"none".  The ADMD believes the host is not authorized but is not willing to make a strong policy statement.  Receiving software SHOULD NOT reject the message based solely on this result, but MAY subject the message to closer scrutiny than normal."  This same reasoning applies to the ~all and -all directives in the SPF (which I see more often).

You'd think that a lot has changed since 2006 (the date of the original SPF spec, RFC4408), that in 2017 a spam filter should fail on that result, but apparently not (sad panda). Kinda makes you wonder what the actual use case is for that tilde character in the definition - I can't think of a good reason to list permitted mail senders, then allow any and every other server too.

That being said, their filter *should* still have caught the mismatch between the "from" and "reply-to" fields, especially since it involved an external source and internal domains.  Or at least paired that up with the domain mismatch to weight this email towards a SPAM decision. But that's another rant altogether.

Long story short - this type of attack was pretty popular (and widely reported) about a year ago, but successful methods never (never ever) go away.  A little bit of research can make for a really well-formed phish, right down to using the right people in the conversation, good grammar, and phrasing appropriate to the people involved.  So a bit of homework can get an attacker a really nice payday, especially if their campaign targets a few hundred companies at a time (and they put more work into their email than the example above)

So in this case, a typo in a DNS record could have cost millions of dollars.  Good security training for the end users and vigilant people made all the difference - a phone call to confirm is a "must-do" step before doing something irrevocable like a wire transfer.

Rob VandenBrink

5 comment(s)


Was it really a typo? Seems to be a common practice, decreasing effectiveness of SPF.

~all was almost 60% in 2015

G Apps says use ~all

Office 365 says use -all
In this case it was a typo - the client did intend (in their SPF) to say "these are my mail servers, all others are imposters and should be blocked".

That being said, at the time, their understanding was that the grammar that they constructed their SPF record with said that.
It looks like there's some less than stellar advice out there from what I'd consider reputable sources, and there are a large number of folks who think their SPF record says one thing, when it really says something else.

Thanks much for the additional info and links!
Prevention is good but cleaning up after the incident is the skill that is really relevant here. CEOs will want immediate answers to:

Q: Was it an inside job? A: Look at the scope of related fake domains.
Q: The fake email's headers don't lead anywhere; how can we learn more A: tag some reply emails.
Q: Money is gone; what can be done A: Call law enforcement, get a case started, ask the bank to claw the money back.

Lots of answers are really easy to implement. Our blog has info from cases of this sort.
I just worked a phish against our HR dept where our SPF with the - did no good at all. I've redacted the headers with, and changed the name/address of the HR boss to HRBoss. This was sent to an HR employee, although the To: field was blank--RCPT TO must have been good.

Not sure what they did, but smtp.mailfrom listed both the bogus and real domains. MS appeared to only check the bogus domain in SPF, which was first...


Received: from
(2a01:111:f400:7e44::208) by
(2603:10b6:404:f9::31) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.933.12 via
Frontend Transport; Thu, 23 Feb 2017 20:51:25 +0000
Authentication-Results: spf=none (sender IP is;; dkim=none (message not
signed) header.d=none;; dmarc=none action=none;; dkim=none (message not signed) header.d=none;

Received-SPF: None ( does not
designate permitted sender hosts)

Received: from ( by ( with Microsoft SMTP
Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id
15.1.919.10 via Frontend Transport; Thu, 23 Feb 2017 20:51:25 +0000
Received: from localhost ([])
by :WBEOUT: with SMTP
id h0LmcdbHokIo0h0LmcbBkd; Thu, 23 Feb 2017 13:50:54 -0700
X-SID: h0LmcdbHokIo0
Received: (qmail 24825 invoked by uid 99); 23 Feb 2017 20:50:54 -0000
Content-Type: multipart/mixed; boundary="=_e098c0bb5dcd7931046c4bb3a575cda6"
User-Agent: Workspace Webmail 6.6.7
Message-ID: <>
From: HR Boss <>
Subject: Request
Date: Thu, 23 Feb 2017 13:50:52 -0700
MIME-Version: 1.0
X-CMAE-Envelope: MS4wfJHgvRCC1vDgYSiKtjMRr63AmplbZmcL6F8qdqsq+OQ7oaJvAAd3ZtDNyF5RMaZy0JmuAqSY3AlSzzY0iqhQtyh++EBfLUmr6/iBWoc6D3Hd+THin1u7
SPF is being made more and more worthless every day by "the cloud". Every Office 365 user has the same SPF record, home user, college student or major corporation. Etc.

Mismatches between Envelope-Sender and From are a great way to catch a lot of this stuff. We have a custom rule that looks for the string "" in the From field. If the Envelope-Sender does not match it's off to the quarantine field. It caught a really nice one once, completely unintended.

The display name was the CEO's name AND his email address but the From address was not our domain.Looking for the string inadvertently caught another one.

Want a good laugh? Pull up the SPF records for the three major credit bureaus. - soft-fail but they use IP networks only. - not only no modifier so it defaults to a neutral which is worse than a soft-fail, they include all of's customers as well as some mass-mailers. - a neutral (?all) which is even worse than a soft-fail.

The only one I've ever seen that was worse was from an IT services company: +all

Yeah, I had to look it up. Effectively it says "We have absolutely no clue who is sending email using our domain so assume it is all authorized."

And if you have domains that never send email, consider setting an SPF record of "v=spf1 -all". That means the domain never sends any email so it's all phony.

The best thing about SPF is it lets you set up DMARC so you can get feedbacl on who is forging your emails.

Diary Archives