1

We recently received an email from a self described "white hat hacker" purporting to be from our own organization.

According to the mail headers, spf, dmarc, dkim and arc all passed okay and gmail didn't flag it in anyway.

We use google domains for our email and the spf/dmarc record in question for the domain is

SPF v=spf1 include:_spf.google.com -all

DMARC _dmarc.companyX.com v=DMARC1; p=none; pct=100; rua=mailto:john.smith@companyX.com

(I realise the DMARC setting is quarantining none at the moment, but I don't believe this would have helped as all the checks passed)

The SPF pass (and there are two of them - one from our domain, and one from the original sender domain)

Received-SPF: pass (google.com: domain of enquiries+xyz@companyX.com designates 209.85.220.69 as permitted sender) client-ip=209.85.220.69;

Received-SPF: pass (google.com: domain of MrWhiteHat@inbox.eu designates 195.216.236.82 as permitted sender) client-ip=195.216.236.82;

From what I can understand, as we have specified _spf.google.com (and it's associated IP's) as a permitted sender, any email sent using those servers (ie, by any gmail user) is valid. My understanding is is obviously wrong, but I'm not sure why/how, or more importantly, what do I need to change in order to prevent this spoofing from passing.

I've found references to a vulnerability in gmail where the attacker uses inbound gateways to bypass the internal SPF check, but this was fixed back in August, and as far as I can see, the SPF check is actually being made (and passing) - https://ezh.es/blog/2020/08/the-confused-mailman-sending-spf-and-dmarc-passing-mail-as-any-gmail-or-g-suite-customer/ and https://www.forbes.com/sites/leemathews/2020/08/20/google-fixed-a-dangerous-gmail-bug-that-allowed-email-spoofing/

There is this similar question - How did a phishing email pass SPF, DKIM and DMARC? but I do not think that is relevant as the email in that question was actually from a different domain (From: uber, instead of From: Bank of America), where as the From: in this email was explicity CompanyX), and there is no resolution in that question about how to block senders like this.

Questions

  1. What stops any gmail user from being able to impersonate any other company that authorizes _spf.google.com as a sender?

  2. What can I change in my set up to prevent this from happening?

Thanks


Semi complete headers - have stripped out some that I think are irrelevant for space reasons.

Delivered-To: john.smith@companyX.com
Return-Path: <enquiries+xyz@companyX.com>
Received: from mail-sor-f69.google.com (mail-sor-f69.google.com. [209.85.220.69])
        by mx.google.com with SMTPS id a77sor4025261wme.15.2020.12.10.15.34.18
        for <john.smith@companyX.com>
        (Google Transport Security);
        Thu, 10 Dec 2020 15:34:19 -0800 (PST)
Received-SPF: pass (google.com: domain of enquiries+xyz@companyX.com designates 209.85.220.69 as permitted sender) client-ip=209.85.220.69;
Authentication-Results: mx.google.com;
       dkim=pass header.i=@companyX-com.20150623.gappssmtp.com header.s=20150623 header.b="xcnlWAQ/";
       arc=pass (i=2 spf=pass spfdomain=inbox.eu dkim=pass dkdomain=inbox.eu dmarc=pass fromdomain=inbox.eu);
       spf=pass (google.com: domain of enquiries+xyz@companyX.com designates 209.85.220.69 as permitted sender) smtp.mailfrom=enquiries+xyz@companyX.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=companyX.com
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@inbox.eu header.s=20140211 header.b=OQtRvw0v;
       spf=pass (google.com: domain of MrWhiteHat@inbox.eu designates 195.216.236.82 as permitted sender) smtp.mailfrom=MrWhitehattester@inbox.eu;
       dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=inbox.eu
Received: from eu-shark2.inbox.eu (eu-shark2.inbox.eu. [195.216.236.82])
        by mx.google.com with ESMTPS id v7si6670766wra.295.2020.12.10.15.34.17
        for <enquiries@companyX.com>
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Thu, 10 Dec 2020 15:34:17 -0800 (PST)
Received-SPF: pass (google.com: domain of MrWhiteHat@inbox.eu designates 195.216.236.82 as permitted sender) client-ip=195.216.236.82;
Received: from eu-shark2.inbox.eu (localhost [127.0.0.1])
    by eu-shark2-out.inbox.eu (Postfix) with ESMTP id B3004442C39
    for <enquiries@companyX.com>; Fri, 11 Dec 2020 01:34:16 +0200 (EET)
Received: from localhost (localhost [127.0.0.1])
    by eu-shark2-in.inbox.eu (Postfix) with ESMTP id A70E64428EF
    for <enquiries@companyX.com>; Fri, 11 Dec 2020 01:34:16 +0200 (EET)
Received: from eu-shark2.inbox.eu ([127.0.0.1])
    by localhost (eu-shark2.inbox.eu [127.0.0.1]) (spamfilter, port 35)
    with ESMTP id CNGUsZY_Hba1 for <enquiries@companyX.com>;
    Fri, 11 Dec 2020 01:34:16 +0200 (EET)
Received: from mail.inbox.eu (eu-pop1 [127.0.0.1])
    by eu-shark2-in.inbox.eu (Postfix) with ESMTP id 08A1B440DC5
    for <enquiries@companyX.com>; Fri, 11 Dec 2020 01:34:16 +0200 (EET)
Received: from DESKTOPR10AFHO (unknown [39.34.131.177])
    (Authenticated sender: MrWhiteHat@inbox.eu)
    by mail.inbox.eu (Postfix) with ESMTPA id 36E2F1BE00DA
    for <enquiries@companyX.com>; Fri, 11 Dec 2020 01:34:14 +0200 (EET)
From: "'Mr White Hat' via Sales & Enquiries" <enquiries@companyX.com>
To: <enquiries@companyX.com>
X-Original-Sender: MrWhiteHat@inbox.eu
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@inbox.eu header.s=20140211 header.b=OQtRvw0v;       spf=pass
 (google.com: domain of MrWhiteHat@inbox.eu designates 195.216.236.82
 as permitted sender) smtp.mailfrom=Whitehattester@inbox.eu;
       dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=inbox.eu
X-Original-From: "Mr White Hat" <Whitehattester@inbox.eu>
Reply-To: "Mr White Hat" <Whitehattester@inbox.eu>```
Dave Smylie
  • 113
  • 6

1 Answers1

2

I can't figure out how to massage your redacted headers into something Google's Messageheader tool can read, but that'd be a good first step. Google will walk you through what it did with a little more authority than I have (especially given your redactions).

Manually reading through your headers (and assuming none are forged), this comes through inbox.eu and passes their SPF. The ARC-Authentication-Results header, which uses Authenticated Received Chain to extend trust (in this case from Google to Google), has some interesting data: Note the part that says header.from=inbox.eu — the From header somehow changed after this header was added but before the Authentication-Results header was added.

Using what ARC says is the original From domain, this passes inbox.eu's DMARC thanks to SPF and alignment with the original From header. That header then magically changes to your company (perhaps via a GMail filter within the attacker's account?) and because it's already in Google's infrastructure, it then passes SPF.

This looks a lot like the patched vuln you referenced.


SPF isn't great at shared hosts. Google tries to mitigate that by verifying the SMTP mail from command and From header address are provably yours, but something went wrong in that final hop (after the ARC header, that topmost Authentication-Results and Received-SPF tied to the topmost Received header).

Rather than being beholden to Google, I recommend setting an SPF record of v=spf1 ?all (which says "SPF can neither pass nor fail") and using DKIM instead. DMARC requires either DKIM or SPF to pass with alignment, so an attack that can tweak the From header domain within Google's infrastructure won't help create an SPF pass that gets the nod from DMARC. Forging DKIM requires breaking cryptography or tricking some server with the authority to sign on behalf of your domain.

If you have hosts that need to send mail without DKIM, add them explicitly (by IP address or very tight IP CIDR) to that SPF record, but don't bless all of Google when you can just configure Google to use your domain for DKIM.

All responsible Email Service Providers and email marketing systems support DKIM as well. Don't forget to go back to DMARC p=none and actually monitor your aggregate logs to figure out what email systems you may have missed.

Adam Katz
  • 9,718
  • 2
  • 22
  • 44