diff --git a/detection-rules/attachment_sus_employee_doc.yml b/detection-rules/attachment_sus_employee_doc.yml index 051133c778d..203dfae8f59 100644 --- a/detection-rules/attachment_sus_employee_doc.yml +++ b/detection-rules/attachment_sus_employee_doc.yml @@ -4,98 +4,174 @@ type: "rule" severity: "medium" source: | type.inbound - // NOTE: This rule is designed for these values to match/sync subject.base and file names + // NOTE: mirror ALL changes between subject & attachments and ( - // the subject contains pay related items + // the subject contains pay related keywords ( - strings.icontains(subject.base, 'salary') - or regex.icontains(subject.base, '\bpay(?:out|roll|\b)') - or strings.icontains(subject.base, 'remuneration') - or strings.icontains(subject.base, 'bonus') - or strings.icontains(subject.base, 'incentive') - or strings.icontains(subject.base, 'merit\b') - or strings.icontains(subject.base, 'handbook') - or strings.icontains(subject.base, 'benefits') - or strings.icontains(subject.base, 'earnings') - or strings.icontains(subject.base, 'contract') - or regex.icontains(subject.base, 'empl[o0]yment') + ( + strings.icontains(subject.base, "benefits") + and not strings.icontains(subject.base, "fidelity netbenefits") + ) + or strings.icontains(subject.base, "bonus") + or ( + regex.icontains(subject.base, '(?:\bcomp\b|compensation)') + and not strings.icontains(subject.base, "broker") + ) + or strings.icontains(subject.base, "earnings") + or regex.icontains(subject.base, 'empl[o0]y(?:ment|ee)') + or ( + strings.icontains(subject.base, "financial") + and not strings.icontains(subject.base, "statement") + ) + or strings.icontains(subject.base, "handbook") + or strings.icontains(subject.base, "incentive") + or regex.icontains(subject.base, 'merit\b') + or regex.icontains(subject.base, '\bpay(?:out|roll)?\b') + or strings.icontains(subject.base, "remuneration") + or strings.icontains(subject.base, "salary") ) and ( - strings.icontains(subject.base, 'review') - or strings.icontains(subject.base, 'breakdown') - or strings.icontains(subject.base, 'Access Your') - or strings.icontains(subject.base, 'evaluation') + strings.icontains(subject.base, "access your") + or strings.icontains(subject.base, "acknowledg") + or regex.icontains(subject.base, 'adjust(?:ed|ment)') + or regex.icontains(subject.base, 'amend(?:ed|ment)') + or strings.icontains(subject.base, "appraisal") + or strings.icontains(subject.base, "assessment") + or strings.icontains(subject.base, "breakdown") + or strings.icontains(subject.base, "change") + or strings.icontains(subject.base, "details") + or strings.icontains(subject.base, "distribution") or regex.icontains(subject.base, 'eval\b') - or strings.icontains(subject.base, 'assessment') - or strings.icontains(subject.base, 'appraisal') - or strings.icontains(subject.base, 'feedback') - or strings.icontains(subject.base, 'performance') - or strings.icontains(subject.base, 'adjustment') - or strings.icontains(subject.base, 'qualification') - or strings.icontains(subject.base, 'increase') - or strings.icontains(subject.base, 'raise') - or strings.icontains(subject.base, 'change') - or strings.icontains(subject.base, 'modification') - or strings.icontains(subject.base, 'distribution') - or strings.icontains(subject.base, 'details') + or strings.icontains(subject.base, "evaluation") + or strings.icontains(subject.base, "feedback") + or strings.icontains(subject.base, "increase") + or strings.icontains(subject.base, "increment") + or strings.icontains(subject.base, "info") + or strings.icontains(subject.base, "modification") + or strings.icontains(subject.base, "notification") + or strings.icontains(subject.base, "performance") + or strings.icontains(subject.base, "plan") + or strings.icontains(subject.base, "qualification") + or strings.icontains(subject.base, "raise") + or ( + strings.icontains(subject.base, "review") + and not strings.icontains(subject.base, "preview") + ) or regex.icontains(subject.base, 'revis(?:ed|ion)') - or regex.icontains(subject.base, 'amend(?:ed|ment)') - or regex.icontains(subject.base, 'update(?:d| to)') - or strings.icontains(subject.base, 'plan') - or strings.icontains(subject.base, 'notification') + or strings.icontains(subject.base, "statement") + or regex.icontains(subject.base, 'update(?:d| to)?') + or regex.icontains(subject.base, + '(January|February|March|April|May|June|July|August|September|October|November|December)\s20[2,3]{1}\d{1}' + ) + ) + // general strings negations + and not ( + strings.icontains(subject.base, "error") + or regex.icontains(subject.base, '\bapp(?:lication)?\b') ) ) + + // the attachment contains pay related keywords and 0 < length(attachments) <= 3 and any(attachments, - .file_extension in ("doc", "docx", "docm", "pdf", "pptx") + ( + // typical observed extentions + .file_extension in ("doc", "docx", "docm", "pdf", "pptx") + // missing extensions + or .file_extension is null + // magic bytes + or .file_type in ("doc", "docx", "pdf", "pptx") + // attached EML + or (.content_type == "message/rfc822" or .file_extension =~ "eml") + ) and ( - strings.icontains(.file_name, 'salary') - or strings.icontains(.file_name, 'compensation') - or regex.icontains(.file_name, '\bpay(?:roll|\b)') - or strings.icontains(.file_name, 'bonus') - or strings.icontains(.file_name, 'incentive') - or strings.icontains(.file_name, 'merit\b') - or strings.icontains(.file_name, 'handbook') - or strings.icontains(.file_name, 'benefits') - or regex.icontains(.file_name, 'empl[o0]yment') + ( + strings.icontains(.file_name, "benefits") + and not strings.icontains(.file_name, "fidelity netbenefits") + ) + or strings.icontains(.file_name, "bonus") + or ( + regex.icontains(.file_name, '(?:\bcomp\b|compensation)') + and not (strings.icontains(.file_name, "broker")) + ) + or regex.icontains(.file_name, 'empl[o0]y(?:ment|ee)') + or ( + strings.icontains(.file_name, "financial") + and not strings.icontains(.file_name, "statement") + ) + or strings.icontains(.file_name, "handbook") + or strings.icontains(.file_name, "incentive") + or regex.icontains(.file_name, 'merit\b') + or regex.icontains(.file_name, '\bpay(?:out|roll)?\b') + or strings.icontains(.file_name, "remuneration") + or strings.icontains(.file_name, "salary") ) and ( - strings.icontains(.file_name, 'review') - or strings.icontains(.file_name, 'evaluation') + strings.icontains(.file_name, "access your") + or strings.icontains(.file_name, "acknowledg") + or regex.icontains(.file_name, 'adjust(?:ed|ment)') + or regex.icontains(.file_name, 'amend(?:ed|ment)') + or strings.icontains(.file_name, "appraisal") + or strings.icontains(.file_name, "assessment") + or strings.icontains(.file_name, "breakdown") + or strings.icontains(.file_name, "change") + or strings.icontains(.file_name, "details") + or strings.icontains(.file_name, "distribution") or regex.icontains(.file_name, 'eval\b') - or strings.icontains(.file_name, 'assessment') - or strings.icontains(.file_name, 'appraisal') - or strings.icontains(.file_name, 'feedback') - or strings.icontains(.file_name, 'performance') - or strings.icontains(.file_name, 'adjustment') - or strings.icontains(.file_name, 'increase') - or strings.icontains(.file_name, 'increment') - or strings.icontains(.file_name, 'raise') - or strings.icontains(.file_name, 'change') - or strings.icontains(.file_name, 'modification') - or strings.icontains(.file_name, 'distribution') - or strings.icontains(.file_name, 'statement') + or strings.icontains(.file_name, "evaluation") + or strings.icontains(.file_name, "feedback") + or strings.icontains(.file_name, "increase") + or strings.icontains(.file_name, "increment") + or strings.icontains(.file_name, "info") + or strings.icontains(.file_name, "modification") + or strings.icontains(.file_name, "notification") + or strings.icontains(.file_name, "performance") + or strings.icontains(.file_name, "plan") + or strings.icontains(.file_name, "qualification") + or strings.icontains(.file_name, "raise") + or ( + strings.icontains(.file_name, "review") + and not strings.icontains(.file_name, "preview") + ) or regex.icontains(.file_name, 'revis(?:ed|ion)') - or regex.icontains(.file_name, 'amend(?:ed|ment)') - or regex.icontains(.file_name, 'adjust(?:ed|ment)') - or regex.icontains(.file_name, 'update(?:d| to)') + or strings.icontains(.file_name, "statement") + or regex.icontains(.file_name, 'update(?:d| to)?') or regex.icontains(.file_name, '(January|February|March|April|May|June|July|August|September|October|November|December)\s20[2,3]{1}\d{1}' ) - or strings.icontains(.file_name, 'contract') or ( // file name contains recipient's email any(recipients.to, strings.icontains(..file_name, .email.email) and .email.domain.valid ) + // file name contains recipient's sld + or any(recipients.to, + strings.icontains(..file_name, .email.domain.sld) + and .email.domain.valid + ) ) ) ) + + // topic negations + and not any(ml.nlu_classifier(body.current_thread.text).topics, + .name == "Newsletters and Digests" + ) + + // negate legitimate conversations + and not ( + (length(headers.references) > 0 or headers.in_reply_to is not null) + and (subject.is_forward or subject.is_reply) + and length(body.previous_threads) >= 1 + ) + + // negate high trust sender domains unless they fail authentication and not ( sender.email.domain.root_domain in $high_trust_sender_root_domains and coalesce(headers.auth_summary.dmarc.pass, false) ) + attack_types: - "Credential Phishing" tactics_and_techniques: