Detection rules › Sublime MQL

Spam: Personalized subject and greetings via Salesforce Marketing Cloud

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

Detects messages sent through Salesforce Marketing Cloud infrastructure that contain a fake previous email thread, where both the current and previous threads start with the same greeting pattern extracted from the subject line.

Threat classification

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

CategoryValues
Attack typesSpam
Tactics and techniquesSocial engineering

Event coverage

Rule body MQL

type.inbound
// attempt to find SF sending infra 
and (
  headers.domains[0].root_domain == "exacttarget.com"
  or strings.iends_with(headers.message_id, '.xt.local>')
  or any(headers.hops,
         any(.fields,
             .name =~ "X-SFMC-Stack"
             or (.name =~ "x-job" and regex.match(.value, '^\d+_\d+$'))
         )
  )
)
// the message contains a fake previous thread
and length(body.previous_threads) == 1

// extract the name from the subject
and any(regex.iextract(subject.base, '(?:^|: )(?P<first_name>[A-Z][a-z]+)$'),
        // the current thread starts with "Hi <extracted from subject>
        strings.istarts_with(body.current_thread.text,
                             strings.concat('Hi ', .named_groups["first_name"])
        )
        // the previous thread starts with "Hi <extracted from subject>
        and any(body.previous_threads,
                strings.istarts_with(.text,
                                     strings.concat('Hi ',
                                                    ..named_groups["first_name"]
                                     )
                )
        )
)

Detection logic

Scope: inbound message.

Detects messages sent through Salesforce Marketing Cloud infrastructure that contain a fake previous email thread, where both the current and previous threads start with the same greeting pattern extracted from the subject line.

  1. inbound message
  2. any of:
    • headers.domains[0].root_domain is 'exacttarget.com'
    • headers.message_id ends with '.xt.local>'
    • any of headers.hops where:
      • any of .fields where any holds:
        • .name is 'X-SFMC-Stack'
        • all of:
          • .name is 'x-job'
          • .value matches '^\\d+_\\d+$'
  3. length(body.previous_threads) is 1
  4. any of regex.iextract(subject.base) where all hold:
    • strings.istarts_with(body.current_thread.text)
    • any of body.previous_threads where:
      • strings.istarts_with(.text)

Inspects: body.current_thread.text, body.previous_threads, body.previous_threads[].text, headers.domains[0].root_domain, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.message_id, subject.base, type.inbound. Sensors: regex.iextract, regex.match, strings.concat, strings.iends_with, strings.istarts_with.

Indicators matched (6)

FieldMatchValue
headers.domains[0].root_domainequalsexacttarget.com
strings.iends_withsuffix.xt.local>
headers.hops[].fields[].nameequalsX-SFMC-Stack
headers.hops[].fields[].nameequalsx-job
regex.matchregex^\d+_\d+$
regex.iextractregex(?:^|: )(?P<first_name>[A-Z][a-z]+)$