Credential phishing: 'Secure message' and engaging language

Body contains language resembling credential theft, and a "secure message" from an untrusted sender.

Sublime rule (View on GitHub)

  1name: "Credential phishing: 'Secure message' and engaging language"
  2description: |
  3    Body contains language resembling credential theft, and a "secure message" from an untrusted sender.
  4type: "rule"
  5severity: "medium"
  6source: |
  7  type.inbound
  8  and (
  9    any(ml.nlu_classifier(body.current_thread.text).intents,
 10        .name == "cred_theft" and .confidence == "high"
 11    )
 12    or any(ml.nlu_classifier(beta.ocr(beta.message_screenshot()).text).intents,
 13           .name == "cred_theft" and .confidence in ("medium", "high")
 14    )
 15  )
 16  
 17  // ----- other suspicious signals here -----
 18  and (
 19    (
 20      regex.icontains(body.current_thread.text, "secure (message|directory)")
 21      or strings.icontains(body.current_thread.text, "document portal")
 22      or strings.icontains(body.current_thread.text, "encrypted message")
 23      or strings.icontains(body.current_thread.text, "protected message")
 24    )
 25    or any(body.previous_threads,
 26           regex.icontains(.text, "secure (message|directory)")
 27           or strings.icontains(.text, "document portal")
 28           or strings.icontains(.text, "encrypted message")
 29           or strings.icontains(.text, "protected message")
 30    )
 31  )
 32  // todo: automated display name / human local part
 33  // todo: suspicious link (unfurl click trackers)
 34  
 35  // ----------
 36  
 37  // has at least 1 link
 38  and length(body.links) > 0
 39  
 40  // negate legitimate message senders
 41  and (
 42    sender.email.domain.root_domain not in ("protectedtrust.com")
 43    and any(body.links,
 44            .href_url.domain.root_domain != sender.email.domain.root_domain
 45    )
 46    // Negate known secure mailer(s)
 47    and not all(body.links,
 48                .href_url.domain.root_domain in (
 49                  "mimecast.com",
 50                  "cisco.com",
 51                  "csiesafe.com"
 52                )
 53    )
 54    and any(headers.hops,
 55            .index == 0
 56            and not any(.fields,
 57                        strings.contains(.value,
 58                                         'multipart/mixed; boundary="PROOFPOINT_BOUNDARY_1"'
 59                        )
 60            )
 61    )
 62    and not (
 63      length(filter(attachments,
 64                    strings.ilike(.file_name,
 65                                  "logo.*",
 66                                  "lock.gif",
 67                                  "SecureMessageAtt.html"
 68                    )
 69             )
 70      ) == 3
 71      and any(attachments,
 72              .file_type == "html"
 73              and any(file.explode(.),
 74                      .scan.html.title == "Proofpoint Encryption"
 75                      and any(.scan.url.urls,
 76                              strings.iends_with(.path,
 77                                                 'formpostdir/safeformpost.aspx'
 78                              )
 79                      )
 80              )
 81              and strings.count(file.parse_html(.).raw, 'name="msg') > 3
 82      )
 83    )
 84    and not (
 85      any(headers.hops,
 86          any(.fields,
 87              .name in (
 88                'X-ZixNet',
 89                'X-VPM-MIV',
 90                'X-VPM-ActionCode',
 91                'X-VPM-SmtpTo'
 92              )
 93          )
 94      )
 95      and any(headers.domains,
 96              .root_domain in (
 97                "zixport.com",
 98                "zixcorp.com",
 99                "zixmail.net",
100                "zixworks.com"
101              )
102      )
103    )
104    and not (
105      any(headers.hops, any(.fields, .name == 'X-SendInc-Message-Id'))
106      and any(headers.domains, .root_domain in ("sendinc.net"))
107    )
108    // negating Mimecast sends with MS banner and/or sender's email pulled out as a link
109    and not length(filter(body.links,
110                          (
111                            .display_text is null
112                            and .display_url.url == sender.email.domain.root_domain
113                          )
114                          or .href_url.domain.root_domain in (
115                            "aka.ms",
116                            "mimecast.com",
117                            "cisco.com"
118                          )
119                   )
120    ) == length(body.links)
121  )
122  and (
123    (
124      profile.by_sender().prevalence in ("new", "outlier")
125      and not profile.by_sender().solicited
126    )
127    or (
128      profile.by_sender().any_messages_malicious_or_spam
129      and not profile.by_sender().any_messages_benign
130    )
131  )
132  and not profile.by_sender().any_messages_benign
133  
134  // negate highly trusted sender domains unless they fail DMARC authentication
135  and (
136    (
137      sender.email.domain.root_domain in $high_trust_sender_root_domains
138      and not headers.auth_summary.dmarc.pass
139    )
140    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
141  )  
142
143attack_types:
144  - "Credential Phishing"
145tactics_and_techniques:
146  - "Social engineering"
147detection_methods:
148  - "Natural Language Understanding"
149  - "Sender analysis"
150id: "bd95a7b1-dc96-53c1-bb7c-3a0f98b04744"
to-top