From f6533c14e81c4f4d868962f4f753a65646cf2858 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:56:26 -0500 Subject: [PATCH 1/7] Create brand_impersonation_punchbowl.yml --- .../brand_impersonation_punchbowl.yml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 detection-rules/brand_impersonation_punchbowl.yml diff --git a/detection-rules/brand_impersonation_punchbowl.yml b/detection-rules/brand_impersonation_punchbowl.yml new file mode 100644 index 00000000000..db10d1f82a2 --- /dev/null +++ b/detection-rules/brand_impersonation_punchbowl.yml @@ -0,0 +1,22 @@ +name: "Brand impersonation: Punchbowl" +description: "Detects messages impersonating Punchbowl invitations not originating from legitimate Punchbowl domain." +type: "rule" +severity: "medium" +source: | + type.inbound + and strings.icontains(beta.ocr(file.message_screenshot()).text, "punchbowl") + // Phrasing is typically "You're invited" + and strings.icontains(body.current_thread.text, "you're invited") + // Legitimate sender will be from punchbowl + and sender.email.email != "mail@mail.punchbowl.com" + +attack_types: + - "Credential Phishing" +tactics_and_techniques: + - "Impersonation: Brand" + - "Social engineering" +detection_methods: + - "Computer Vision" + - "Content analysis" + - "Optical Character Recognition" + - "Sender analysis" From 2ffc1a677081f7550db60f1ceb465d939fb9b338 Mon Sep 17 00:00:00 2001 From: ID Generator Date: Fri, 26 Sep 2025 18:59:48 +0000 Subject: [PATCH 2/7] Auto add rule ID --- detection-rules/brand_impersonation_punchbowl.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/detection-rules/brand_impersonation_punchbowl.yml b/detection-rules/brand_impersonation_punchbowl.yml index db10d1f82a2..e1167c525a5 100644 --- a/detection-rules/brand_impersonation_punchbowl.yml +++ b/detection-rules/brand_impersonation_punchbowl.yml @@ -20,3 +20,4 @@ detection_methods: - "Content analysis" - "Optical Character Recognition" - "Sender analysis" +id: "58937ba0-6966-559a-bd4f-759ee8b2979e" From c5782f0aa158fcda69957ffe2b5287e15f0f9a63 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:07:22 -0500 Subject: [PATCH 3/7] Update brand_impersonation_punchbowl.yml --- detection-rules/brand_impersonation_punchbowl.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/detection-rules/brand_impersonation_punchbowl.yml b/detection-rules/brand_impersonation_punchbowl.yml index e1167c525a5..93ded2123d0 100644 --- a/detection-rules/brand_impersonation_punchbowl.yml +++ b/detection-rules/brand_impersonation_punchbowl.yml @@ -6,9 +6,12 @@ source: | type.inbound and strings.icontains(beta.ocr(file.message_screenshot()).text, "punchbowl") // Phrasing is typically "You're invited" - and strings.icontains(body.current_thread.text, "you're invited") - // Legitimate sender will be from punchbowl - and sender.email.email != "mail@mail.punchbowl.com" + and ( + strings.icontains(body.current_thread.text, "you're invited") + or (any(body.previous_threads, strings.icontains(.text, "you're invited"))) + ) + // Legitimate sender will be from punchbowl, negating known non-associated domains + and not sender.email.domain.root_domain in ("punchbowl.com", "punchbowl.news") attack_types: - "Credential Phishing" From f283b843dfd0915e07f07f8c58b014a89e6008ff Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Thu, 2 Oct 2025 15:43:40 -0500 Subject: [PATCH 4/7] Update brand_impersonation_punchbowl.yml --- detection-rules/brand_impersonation_punchbowl.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/detection-rules/brand_impersonation_punchbowl.yml b/detection-rules/brand_impersonation_punchbowl.yml index 93ded2123d0..7a7b1154bd8 100644 --- a/detection-rules/brand_impersonation_punchbowl.yml +++ b/detection-rules/brand_impersonation_punchbowl.yml @@ -4,13 +4,19 @@ type: "rule" severity: "medium" source: | type.inbound - and strings.icontains(beta.ocr(file.message_screenshot()).text, "punchbowl") + // Looking for Punchbowl phrasing in all body threads + and ( + strings.icontains(body.current_thread.text, "punchbowl") + or (any(body.previous_threads, strings.icontains(.text, "punchbowl"))) + // Look for alt text in HTML for standardized Evite formatting if string is not avail. + or strings.icontains(body.html.raw, 'alt="Punchbowl"') + ) // Phrasing is typically "You're invited" and ( strings.icontains(body.current_thread.text, "you're invited") or (any(body.previous_threads, strings.icontains(.text, "you're invited"))) ) - // Legitimate sender will be from punchbowl, negating known non-associated domains + // Legitimate sender will be from punchbowl, negating known non-associated domains. and not sender.email.domain.root_domain in ("punchbowl.com", "punchbowl.news") attack_types: @@ -19,8 +25,6 @@ tactics_and_techniques: - "Impersonation: Brand" - "Social engineering" detection_methods: - - "Computer Vision" - "Content analysis" - - "Optical Character Recognition" - "Sender analysis" id: "58937ba0-6966-559a-bd4f-759ee8b2979e" From 7f4dfbf27033dfba810dae736db5fc3013425272 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:19:58 -0500 Subject: [PATCH 5/7] Update brand_impersonation_punchbowl.yml --- detection-rules/brand_impersonation_punchbowl.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/detection-rules/brand_impersonation_punchbowl.yml b/detection-rules/brand_impersonation_punchbowl.yml index 7a7b1154bd8..e26bca5d6e8 100644 --- a/detection-rules/brand_impersonation_punchbowl.yml +++ b/detection-rules/brand_impersonation_punchbowl.yml @@ -7,15 +7,11 @@ source: | // Looking for Punchbowl phrasing in all body threads and ( strings.icontains(body.current_thread.text, "punchbowl") - or (any(body.previous_threads, strings.icontains(.text, "punchbowl"))) - // Look for alt text in HTML for standardized Evite formatting if string is not avail. + // Look for alt text in HTML for standardized Punchbowl formatting if string is not avail. or strings.icontains(body.html.raw, 'alt="Punchbowl"') ) // Phrasing is typically "You're invited" - and ( - strings.icontains(body.current_thread.text, "you're invited") - or (any(body.previous_threads, strings.icontains(.text, "you're invited"))) - ) + and (strings.icontains(body.current_thread.text, "you're invited")) // Legitimate sender will be from punchbowl, negating known non-associated domains. and not sender.email.domain.root_domain in ("punchbowl.com", "punchbowl.news") From 5a2fd4f0b698dc392908bd696922aef88fc92dd0 Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Thu, 9 Oct 2025 17:37:41 -0500 Subject: [PATCH 6/7] Update brand_impersonation_punchbowl.yml Substantial changes to rule logic negating many times of FP's. --- .../brand_impersonation_punchbowl.yml | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/detection-rules/brand_impersonation_punchbowl.yml b/detection-rules/brand_impersonation_punchbowl.yml index e26bca5d6e8..644b7e770a2 100644 --- a/detection-rules/brand_impersonation_punchbowl.yml +++ b/detection-rules/brand_impersonation_punchbowl.yml @@ -4,16 +4,26 @@ type: "rule" severity: "medium" source: | type.inbound - // Looking for Punchbowl phrasing in all body threads - and ( - strings.icontains(body.current_thread.text, "punchbowl") - // Look for alt text in HTML for standardized Punchbowl formatting if string is not avail. - or strings.icontains(body.html.raw, 'alt="Punchbowl"') + and strings.contains(body.html.raw, 'evitecdn.com') + and length(filter(html.xpath(body.html, '//img/@src').nodes, + // calling parse_url allows url decoding to help us + strings.parse_url(.raw).domain.root_domain == 'evitecdn.com' + ) + ) >= 2 + and length(filter(body.links, + .href_url.domain.root_domain == "evite.com" + and regex.contains(.href_url.path, '^/_ct/[a-f0-9]{40}/') + ) + ) < 3 + and not ( + (subject.is_forward or subject.is_reply) + and (length(headers.references) != 0 or headers.in_reply_to is not null) + and length(body.previous_threads) > 0 + ) + and not ( + sender.email.domain.root_domain == "evite.com" + and headers.auth_summary.dmarc.pass ) - // Phrasing is typically "You're invited" - and (strings.icontains(body.current_thread.text, "you're invited")) - // Legitimate sender will be from punchbowl, negating known non-associated domains. - and not sender.email.domain.root_domain in ("punchbowl.com", "punchbowl.news") attack_types: - "Credential Phishing" From 409b7feda85f42116209c830ebb0bbce2addb05e Mon Sep 17 00:00:00 2001 From: "Brandon 2: Brandon Harder" <189403278+missingn0pe@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:56:35 -0500 Subject: [PATCH 7/7] Update brand_impersonation_punchbowl.yml --- .../brand_impersonation_punchbowl.yml | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/detection-rules/brand_impersonation_punchbowl.yml b/detection-rules/brand_impersonation_punchbowl.yml index 644b7e770a2..e26bca5d6e8 100644 --- a/detection-rules/brand_impersonation_punchbowl.yml +++ b/detection-rules/brand_impersonation_punchbowl.yml @@ -4,26 +4,16 @@ type: "rule" severity: "medium" source: | type.inbound - and strings.contains(body.html.raw, 'evitecdn.com') - and length(filter(html.xpath(body.html, '//img/@src').nodes, - // calling parse_url allows url decoding to help us - strings.parse_url(.raw).domain.root_domain == 'evitecdn.com' - ) - ) >= 2 - and length(filter(body.links, - .href_url.domain.root_domain == "evite.com" - and regex.contains(.href_url.path, '^/_ct/[a-f0-9]{40}/') - ) - ) < 3 - and not ( - (subject.is_forward or subject.is_reply) - and (length(headers.references) != 0 or headers.in_reply_to is not null) - and length(body.previous_threads) > 0 - ) - and not ( - sender.email.domain.root_domain == "evite.com" - and headers.auth_summary.dmarc.pass + // Looking for Punchbowl phrasing in all body threads + and ( + strings.icontains(body.current_thread.text, "punchbowl") + // Look for alt text in HTML for standardized Punchbowl formatting if string is not avail. + or strings.icontains(body.html.raw, 'alt="Punchbowl"') ) + // Phrasing is typically "You're invited" + and (strings.icontains(body.current_thread.text, "you're invited")) + // Legitimate sender will be from punchbowl, negating known non-associated domains. + and not sender.email.domain.root_domain in ("punchbowl.com", "punchbowl.news") attack_types: - "Credential Phishing"