diff --git a/detecdetection-rules/credential_phishing_fake_password_expiration.yml b/detecdetection-rules/credential_phishing_fake_password_expiration.yml new file mode 100644 index 00000000000..79f36e2c546 --- /dev/null +++ b/detecdetection-rules/credential_phishing_fake_password_expiration.yml @@ -0,0 +1,68 @@ +name: "Credential Phishing: Fake Password Expiration from New and Unsolicited sender" +description: "This rule looks for password expiration verbiage in the subject and body. It requires between 1 and 9 links in the body. The rule uses NLU in addition to statically specified term anchors. High trust senders are also negated." +type: "rule" +severity: "medium" +source: | + type.inbound + + // no attachments + and length(attachments) == 0 + + // body contains expire, expiration, loose, lose + and regex.icontains(body.current_thread.text, '(expir(e)?ation|lo(o)?se)') + + // subject or body contains account or access + and any([subject.subject, body.current_thread.text], + regex.icontains(body.current_thread.text, "account|access") + ) + + // subject or body must contains password + and any([subject.subject, body.current_thread.text], + regex.icontains(body.current_thread.text, '\bpassword\b') + ) + and any(ml.nlu_classifier(body.current_thread.text).intents, + .name == "cred_theft" and .confidence == "high" + ) + + // sender is new and unsolicited and no previous malicious or spam flaggs + and ( + ( + profile.by_sender().prevalence in ("new", "outlier") + and not profile.by_sender().solicited + ) + or profile.by_sender().any_messages_malicious_or_spam + ) + + // no false positives + and not profile.by_sender().any_false_positives + + // negate highly trusted sender domains unless they fail DMARC authentication + and ( + ( + sender.email.domain.root_domain in $high_trust_sender_root_domains + and ( + any(distinct(headers.hops, .authentication_results.dmarc is not null), + strings.ilike(.authentication_results.dmarc, "*fail") + ) + ) + ) + or sender.email.domain.root_domain not in $high_trust_sender_root_domains + ) + + // body length between 600 and 2000 + and 600 < length(body.current_thread.text) < 2000 + + // not a reply + and ( + length(headers.references) == 0 + or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) + ) + +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Social engineering" +detection_methods: + - "Content analysis" + - "Natural Language Understanding" + - "Sender analysis"