From 756ff0feb99de89d900406238fd15a2970d7f521 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:25:05 -0500 Subject: [PATCH 1/3] Restructured "Attach: Sus Employee Lure" rule Many holistic changes made: - Fix strings/regex logic - Switch attachment inspection style to resolve null inspection - Sort for ease of future revisions - Mirror 1:1 subject & attachment as intended - Remove "contract" as it FP'd after 1:1 - Add missed keywords & strategies - Negated FP keywords - Negated fwd/reply --- .../attachment_sus_employee_doc.yml | 181 +++++++++++------- 1 file changed, 116 insertions(+), 65 deletions(-) diff --git a/detection-rules/attachment_sus_employee_doc.yml b/detection-rules/attachment_sus_employee_doc.yml index 051133c778d..de23937ea15 100644 --- a/detection-rules/attachment_sus_employee_doc.yml +++ b/detection-rules/attachment_sus_employee_doc.yml @@ -4,98 +4,149 @@ 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(?:ensation)?\b') + 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 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}' + ) ) ) + + // the attachment contains pay related keywords and 0 < length(attachments) <= 3 and any(attachments, - .file_extension in ("doc", "docx", "docm", "pdf", "pptx") + .file_type in ("doc", "docx", "pdf", "pptx") 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(?:ensation)?\b') + 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 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 + ) ) ) ) - and not ( - sender.email.domain.root_domain in $high_trust_sender_root_domains - and coalesce(headers.auth_summary.dmarc.pass, false) - ) + +// negate legitimate conversations +and not (subject.is_forward or subject.is_reply) + +// 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: From f2bf594f1df53f0ea6aae79fb1b00d60aaaea702 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Mon, 20 Apr 2026 08:49:41 -0500 Subject: [PATCH 2/3] Resubmitting with correct format Invalid spacing caused failures. Fixed spacing. --- .../attachment_sus_employee_doc.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/detection-rules/attachment_sus_employee_doc.yml b/detection-rules/attachment_sus_employee_doc.yml index de23937ea15..9c88029b064 100644 --- a/detection-rules/attachment_sus_employee_doc.yml +++ b/detection-rules/attachment_sus_employee_doc.yml @@ -137,15 +137,15 @@ source: | ) ) ) - -// negate legitimate conversations -and not (subject.is_forward or subject.is_reply) - -// 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) -) + + // negate legitimate conversations + and not (subject.is_forward or subject.is_reply) + + // 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" From 8a88b7722751d94866b5a13c2d6c1dcd81012f79 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Tue, 21 Apr 2026 17:16:44 -0500 Subject: [PATCH 3/3] Updating Attachment: Policy lure attachment rule Making fine tweaks, adding scope for null files & other attachments, negating topic & updating legit convo logic. --- .../attachment_sus_employee_doc.yml | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/detection-rules/attachment_sus_employee_doc.yml b/detection-rules/attachment_sus_employee_doc.yml index 9c88029b064..203dfae8f59 100644 --- a/detection-rules/attachment_sus_employee_doc.yml +++ b/detection-rules/attachment_sus_employee_doc.yml @@ -14,7 +14,7 @@ source: | ) or strings.icontains(subject.base, "bonus") or ( - regex.icontains(subject.base, '\bcomp(?:ensation)?\b') + regex.icontains(subject.base, '(?:\bcomp\b|compensation)') and not strings.icontains(subject.base, "broker") ) or strings.icontains(subject.base, "earnings") @@ -32,6 +32,7 @@ source: | ) and ( 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") @@ -63,12 +64,26 @@ source: | '(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_type in ("doc", "docx", "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, "benefits") @@ -76,7 +91,7 @@ source: | ) or strings.icontains(.file_name, "bonus") or ( - regex.icontains(.file_name, '\bcomp(?:ensation)?\b') + regex.icontains(.file_name, '(?:\bcomp\b|compensation)') and not (strings.icontains(.file_name, "broker")) ) or regex.icontains(.file_name, 'empl[o0]y(?:ment|ee)') @@ -93,6 +108,7 @@ source: | ) and ( 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") @@ -138,8 +154,17 @@ source: | ) ) + // topic negations + and not any(ml.nlu_classifier(body.current_thread.text).topics, + .name == "Newsletters and Digests" + ) + // negate legitimate conversations - and not (subject.is_forward or subject.is_reply) + 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 (