Detection rules › Sublime MQL

Service abuse: SendGrid impersonation via Sendgrid from new sender

Severity
high
Type
rule
Source
github.com/sublime-security/sublime-rules

Detects messages impersonating SendGrid from new senders, while routing through legitimate SendGrid infrastructure. This pattern is commonly used to abuse trusted email services for malicious purposes.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesImpersonation: Brand, Social engineering

Event coverage

Rule body MQL

type.inbound
// SendGird impersonation patterns
and (
  strings.ilike(strings.replace_confusables(sender.display_name), '*sendgrid*')
  or strings.ilevenshtein(strings.replace_confusables(sender.display_name),
                          'sendgrid'
  ) <= 1
  or (
    strings.ilike(strings.replace_confusables(sender.email.local_part),
                  '*sendgrid*'
    )
    and (
      sender.display_name is null
      or strings.ilike(strings.replace_confusables(subject.base), '*sendgrid*')
    )
  )
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "SendGrid" and .confidence == "high"
  )
)
// sent from sendgrid infra
and any(headers.domains,
        strings.icontains(.domain, 'outbound-mail.sendgrid.net')
)
// not common senders with valid domains
// this catches cases where the domain is invalid and senders become common
and not (
  profile.by_sender_email().prevalence == "common" and sender.email.domain.valid
)

// negate legit sendgrid messages
and not (
  sender.email.domain.domain == "sendgrid.com"
  and coalesce(headers.auth_summary.dmarc.pass, false)
)

Detection logic

Scope: inbound message.

Detects messages impersonating SendGrid from new senders, while routing through legitimate SendGrid infrastructure. This pattern is commonly used to abuse trusted email services for malicious purposes.

  1. inbound message
  2. any of:
    • strings.replace_confusables(sender.display_name) matches '*sendgrid*'
    • strings.replace_confusables(sender.display_name) is similar to 'sendgrid'
    • all of:
      • strings.replace_confusables(sender.email.local_part) matches '*sendgrid*'
      • any of:
        • sender.display_name is missing
        • strings.replace_confusables(subject.base) matches '*sendgrid*'
    • any of ml.logo_detect(file.message_screenshot()).brands where all hold:
      • .name is 'SendGrid'
      • .confidence is 'high'
  3. any of headers.domains where:
    • .domain contains 'outbound-mail.sendgrid.net'
  4. not:
    • all of:
      • profile.by_sender_email().prevalence is 'common'
      • sender.email.domain.valid
  5. not:
    • all of:
      • sender.email.domain.domain is 'sendgrid.com'
      • coalesce(headers.auth_summary.dmarc.pass)

Inspects: headers.auth_summary.dmarc.pass, headers.domains, headers.domains[].domain, sender.display_name, sender.email.domain.domain, sender.email.domain.valid, sender.email.local_part, subject.base, type.inbound. Sensors: file.message_screenshot, ml.logo_detect, profile.by_sender_email, strings.icontains, strings.ilevenshtein, strings.ilike, strings.replace_confusables.

Indicators matched (6)

FieldMatchValue
strings.ilikesubstring*sendgrid*
strings.ilevenshteinfuzzysendgrid
ml.logo_detect(file.message_screenshot()).brands[].nameequalsSendGrid
ml.logo_detect(file.message_screenshot()).brands[].confidenceequalshigh
strings.icontainssubstringoutbound-mail.sendgrid.net
sender.email.domain.domainequalssendgrid.com