Detection rules › Sublime MQL

Attachment: EML with suspicious indicators

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

Attached EML contains suspicious indicators, such as a missing sender email or short HTML body.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesEvasion, HTML smuggling, Social engineering

Event coverage

Rule body MQL

type.inbound
and (
  // a single attachmed EML
  length(attachments) == 1
  // or a single attached EML with one or more images used in the body of the message
  // likely within the signatures
  or (
    length(filter(attachments,
                  .file_extension == "eml" or .content_type == "message/rfc822"
           )
    ) == 1
    and length(filter(attachments,
                      .file_type in $file_types_images
                      and (
                        any(regex.extract(.content_id, '^<(?P<cid>.*)\>$'),
                            strings.icontains(body.html.raw,
                                              .named_groups["cid"]
                            )
                        )
                        or strings.icontains(body.html.raw, .content_id)
                      )
               )
    ) == length(attachments) - 1
  )
)
and (
  length(body.current_thread.text) < 300
  or body.current_thread.text is null
  or any(ml.nlu_classifier(body.current_thread.text).intents,
         .name in ("cred_theft", "steal_pii")
  )
)
and not any(ml.nlu_classifier(body.current_thread.text).intents,
            .name == "benign" and .confidence == "high"
)
and any(attachments,
        (.file_extension == "eml" or .content_type == "message/rfc822")
        and (
          // suspicious indicators
          file.parse_eml(.).sender.email.email == ""
          or length(file.parse_eml(.).body.html.raw) < 10
          or length(file.parse_eml(.).headers.hops) < 2
          // the sender of the outer message is the recipient of the outer message
          // and the sender and recipient of the inner message
          or (
            sender.email.email in map(recipients.to, .email.email)
            and length(recipients.to) == 1
            and sender.email.email == file.parse_eml(.).sender.email.email
            and sender.email.email in map(file.parse_eml(.).recipients.to,
                                          .email.email
            )
            and length(file.parse_eml(.).recipients.to) == 1
          )
        )
        and not (
          all(file.parse_eml(.).body.links,
              .href_url.domain.root_domain in ("aka.ms", "office365.com")
              or .href_url.url == "#additionalatt"
          )
          and strings.icontains(file.parse_eml(.).body.current_thread.text,
                                "We’re making sure your attachments are safe"
          )
        )
        and file.parse_eml(.).sender.email.domain.root_domain not in $org_domains
)
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)

// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not headers.auth_summary.dmarc.pass
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

Detection logic

Scope: inbound message.

Attached EML contains suspicious indicators, such as a missing sender email or short HTML body.

  1. inbound message
  2. any of:
    • length(attachments) is 1
    • all of:
      • length(filter(attachments, .file_extension == 'eml' or .content_type == 'message/rfc822')) is 1
      • length(filter(attachments, .file_type in $file_types_images and any(regex.extract(.content_id, '^<(?P<cid>.*)\\>$'), strings.icontains(body.html.raw, .named_groups['cid'])) or strings.icontains(body.html.raw, .content_id))) is length(attachments) - 1
  3. any of:
    • length(body.current_thread.text) < 300
    • body.current_thread.text is missing
    • any of ml.nlu_classifier(body.current_thread.text).intents where:
      • .name in ('cred_theft', 'steal_pii')
  4. not:
    • any of ml.nlu_classifier(body.current_thread.text).intents where all hold:
      • .name is 'benign'
      • .confidence is 'high'
  5. any of attachments where all hold:
    • any of:
      • .file_extension is 'eml'
      • .content_type is 'message/rfc822'
    • any of:
      • file.parse_eml(.).sender.email.email is ''
      • length(file.parse_eml(.).body.html.raw) < 10
      • length(file.parse_eml(.).headers.hops) < 2
      • all of:
        • sender.email.email in map(recipients.to, .email.email)
        • length(recipients.to) is 1
        • sender.email.email is file.parse_eml(.).sender.email.email
        • sender.email.email in map(file.parse_eml(.).recipients.to, .email.email)
        • length(file.parse_eml(.).recipients.to) is 1
    • not:
      • all of:
        • all of file.parse_eml(.).body.links where any holds:
          • .href_url.domain.root_domain in ('aka.ms', 'office365.com')
          • .href_url.url is '#additionalatt'
        • file.parse_eml(.).body.current_thread.text contains 'We’re making sure your attachments are safe'
    • file.parse_eml(.).sender.email.domain.root_domain not in $org_domains
  6. any of:
    • not:
      • profile.by_sender().solicited
    • all of:
      • profile.by_sender().any_messages_malicious_or_spam
      • not:
        • profile.by_sender().any_messages_benign
  7. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • headers.auth_summary.dmarc.pass
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains

Inspects: attachments[].content_id, attachments[].content_type, attachments[].file_extension, attachments[].file_type, body.current_thread.text, body.html.raw, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].email.email, sender.email.domain.root_domain, sender.email.email, type.inbound. Sensors: file.parse_eml, ml.nlu_classifier, profile.by_sender, regex.extract, strings.icontains. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.

Indicators matched (11)

FieldMatchValue
attachments[].file_extensionequalseml
attachments[].content_typeequalsmessage/rfc822
regex.extractregex^<(?P<cid>.*)\>$
ml.nlu_classifier(body.current_thread.text).intents[].namemembercred_theft
ml.nlu_classifier(body.current_thread.text).intents[].namemembersteal_pii
ml.nlu_classifier(body.current_thread.text).intents[].nameequalsbenign
ml.nlu_classifier(body.current_thread.text).intents[].confidenceequalshigh
file.parse_eml(attachments[]).body.links[].href_url.domain.root_domainmemberaka.ms
file.parse_eml(attachments[]).body.links[].href_url.domain.root_domainmemberoffice365.com
file.parse_eml(attachments[]).body.links[].href_url.urlequals#additionalatt
strings.icontainssubstringWe’re making sure your attachments are safe