diff --git a/signals/attachment_count.yml b/signals/attachments/attachment_count.yml similarity index 100% rename from signals/attachment_count.yml rename to signals/attachments/attachment_count.yml diff --git a/signals/attachment_filesizes.yml b/signals/attachments/attachment_filesizes.yml similarity index 100% rename from signals/attachment_filesizes.yml rename to signals/attachments/attachment_filesizes.yml diff --git a/signals/content/body_tracking_pixel.yml b/signals/content/body_tracking_pixel.yml new file mode 100644 index 00000000000..63ea71b5eef --- /dev/null +++ b/signals/content/body_tracking_pixel.yml @@ -0,0 +1,13 @@ +name: "Tracking pixel in HTML body" +type: "query" +source: | + ( + // standard html + regex.contains(body.html.raw, + ']*?width="1(px)?"[^>]*?height="1(px)?"[^>]*?style="[^"]*(visibility:hidden|display:none)[^"]*"[^>]*?>' + ) + // handle quoted printable variants + or regex.contains(body.html.raw, + '' + ) + ) diff --git a/signals/headers/headers_fake_thread.yml b/signals/headers/headers_fake_thread.yml new file mode 100644 index 00000000000..4573126026c --- /dev/null +++ b/signals/headers/headers_fake_thread.yml @@ -0,0 +1,9 @@ +name: "Fake message thread" +type: "query" +source: | + type.inbound + and strings.istarts_with(subject.subject, "RE:") + and ( + length(headers.references) == 0 + or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To"))) + ) diff --git a/signals/headers/headers_gmail_autoforward.yml b/signals/headers/headers_gmail_autoforward.yml new file mode 100644 index 00000000000..b8e4abf63ba --- /dev/null +++ b/signals/headers/headers_gmail_autoforward.yml @@ -0,0 +1,7 @@ +name: "Gmail Auto-Forward" +type: "query" +source: | + any([headers.return_path.email], + strings.ilike(headers.return_path.local_part, "*+caf_=*") and type.inbound + ) + diff --git a/signals/headers/headers_microsoft_scl.yml b/signals/headers/headers_microsoft_scl.yml new file mode 100644 index 00000000000..6f501f14a24 --- /dev/null +++ b/signals/headers/headers_microsoft_scl.yml @@ -0,0 +1,8 @@ +name: "Microsoft SCL" +type: "query" +source: | + filter( + map(headers.hops, + map(filter(.fields, .name =~ "X-ms-exchange-organization-scl"), .value) + ), length(.) > 0 + ) diff --git a/signals/headers/headers_mismatched_from_reply_to.yml b/signals/headers/headers_mismatched_from_reply_to.yml new file mode 100644 index 00000000000..b6c05c0dace --- /dev/null +++ b/signals/headers/headers_mismatched_from_reply_to.yml @@ -0,0 +1,7 @@ +name: "Mismatched From and Reply-to Doms" +type: "query" +source: | + any(headers.reply_to, + length(headers.reply_to) > 0 + and all(headers.reply_to, .email.domain.root_domain != sender.email.domain.root_domain) + ) diff --git a/signals/headers/headers_mismatched_from_return_path.yml b/signals/headers/headers_mismatched_from_return_path.yml new file mode 100644 index 00000000000..4557ab04dad --- /dev/null +++ b/signals/headers/headers_mismatched_from_return_path.yml @@ -0,0 +1,8 @@ +name: "Mismatched From and Return-Path" +type: "query" +source: | + any([headers.return_path.email], + (headers.return_path.email is not null + and headers.return_path.email != sender.email.email + and type.inbound) + ) diff --git a/signals/headers/headers_phishing_simulation_cofense.yml b/signals/headers/headers_phishing_simulation_cofense.yml new file mode 100644 index 00000000000..1a6427e8350 --- /dev/null +++ b/signals/headers/headers_phishing_simulation_cofense.yml @@ -0,0 +1,16 @@ +name: "Cofense PhishMe phishing simulation" +type: "query" +source: | + any(headers.ips, .ip in ( + "13.113.166.58", + "35.182.57.68", + "52.1.96.230", + "52.20.128.29", + "52.20.155.14", + "52.28.182.143", + "52.28.252.18", + "52.29.24.224", + "52.29.5.79", + "52.5.119.169", + "52.62.59.61", + )) diff --git a/signals/headers/headers_phishing_simulation_hoxhunt.yml b/signals/headers/headers_phishing_simulation_hoxhunt.yml new file mode 100644 index 00000000000..97463d5042a --- /dev/null +++ b/signals/headers/headers_phishing_simulation_hoxhunt.yml @@ -0,0 +1,4 @@ +name: "HoxHunt phishing simulation" +type: "query" +source: | + any(headers.hops, strings.ends_with(.signature.domain, ".hoxhuntsigning.com")) diff --git a/signals/headers/headers_phishing_simulation_knowbe4.yml b/signals/headers/headers_phishing_simulation_knowbe4.yml new file mode 100644 index 00000000000..9fc45b7a381 --- /dev/null +++ b/signals/headers/headers_phishing_simulation_knowbe4.yml @@ -0,0 +1,4 @@ +name: "KnowBe4 phishing simulation" +type: "query" +source: | + any(headers.ips, regex.match(.ip, '147\.10\.167\.([0-9]|[0-5][0-9]|6[0-3])', '23.21.109.(197|212)', '52.49.(201.246|235.189)')) diff --git a/signals/headers/headers_undisclosed_recipients.yml b/signals/headers/headers_undisclosed_recipients.yml new file mode 100644 index 00000000000..0f2e86ad8f3 --- /dev/null +++ b/signals/headers/headers_undisclosed_recipients.yml @@ -0,0 +1,6 @@ +name: "Undisclosed Recipients" +type: "query" +source: | + any([recipients.to, recipients.bcc, recipients.cc], + any(., .display_name =~ "Undisclosed recipients:") + ) diff --git a/signals/headers/headers_x_originating_ip.yml b/signals/headers/headers_x_originating_ip.yml new file mode 100644 index 00000000000..07ee4ec53a1 --- /dev/null +++ b/signals/headers/headers_x_originating_ip.yml @@ -0,0 +1,4 @@ +name: "X-Originating-IP" +type: "query" +source: | + headers.x_originating_ip.ip