Skip to content

Commit

Permalink
Merge branch 'main' into microsoft_scl_spam
Browse files Browse the repository at this point in the history
  • Loading branch information
aidenmitchell authored Nov 21, 2023
2 parents 44687ad + 1b78311 commit 9f7cd81
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 7 deletions.
51 changes: 51 additions & 0 deletions detection-rules/image_as_content_open_redir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: "Image as content linking to an open redirect"
description: "Body contains little, no, or only disclaimer text, and an image linking to an open redirect."
type: "rule"
severity: "high"
source: |
type.inbound
and length(body.links) < 3
and 0 < (length(attachments)) < 3
and all(attachments, (.file_type in $file_types_images))
and (
// body text is very short
(
0 <= (length(body.current_thread.text)) < 10
or body.current_thread.text is null
)
or (
length(body.current_thread.text) < 900
// or body is most likely all warning banner (text contains the sender and common warning banner language)
and (
(
strings.contains(body.current_thread.text, sender.email.email)
and strings.contains(body.current_thread.text, 'caution')
)
or regex.icontains(body.current_thread.text,
"intended recipient's use only|external email|sent from outside|you don't often|confidential"
)
)
)
)
and (
any(body.links,
any(.href_url.rewrite.encoders, strings.icontains(., "open_redirect"))
)
or any(body.links,
.href_url.domain.root_domain == 'sng.link'
and strings.ilike(.href_url.query_params, "*fallback_redirect*")
)
)
attack_types:
- "Credential Phishing"
- "Malware/Ransomware"
tactics_and_techniques:
- "Evasion"
- "Image as content"
- "Open redirect"
- "Social engineering"
detection_methods:
- "Content analysis"
- "HTML analysis"
- "URL analysis"
id: "f5cec36b-76ea-5cd6-958b-74f819d73a47"
77 changes: 77 additions & 0 deletions detection-rules/impersonation_recipient_domain_display_name.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: "Display name impersonation using recipient SLD (new sender)"
description: |
The recipient domain's SLD is used in the sender's display name
in order to impersonate the organization.
type: "rule"
severity: "medium"
source: |
type.inbound
and (
// recipient SLD is being impersonated in the subject + display name
(
// these are usually targeted with just 1 recipient,
// but sometimes they CC themselves or have a blank CC
length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2
and any(recipients.to,
// ensure that we're checking the org SLD
.email.domain.sld in $org_slds
and strings.icontains(sender.display_name, .email.domain.sld)
)
)
or (
// accounts for BCC'd messages where the recipients are empty
// if BCC, sometimes the recipient will be the attacker's email
length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2
and strings.icontains(sender.display_name, mailbox.email.domain.sld)
)
)
and (
// at least 1 link or non-image attachment
(
length(body.links) > 0
// these attacks all use compromosed senders, so we look for a domain
// that doesn't match the sender's domain to weed out legit messages
and any(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain)
)
or length(filter(attachments, .file_type not in $file_types_images)) > 0
)
and not (
strings.contains(sender.display_name, "on behalf of")
and sender.email.domain.root_domain == "microsoftonline.com"
)
and all(recipients.to, .email.email != sender.email.email)
// 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
)
and (
(
profile.by_sender().prevalence in ("new", "outlier")
and not profile.by_sender().solicited
)
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_false_positives
)
)
and not profile.by_sender().any_false_positives
attack_types:
- "Credential Phishing"
tactics_and_techniques:
- "Social engineering"
detection_methods:
- "Header analysis"
- "Sender analysis"
id: "81a8ed12-0e26-5998-90ae-03334f358704"
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: "Display name and subject impersonation using recipient SLD (new sender)"
description: |
The recipient domain's SLD is used in the sender's display name
and in the subject to impersonate the organization.
type: "rule"
severity: "medium"
source: |
type.inbound
and (
// recipient SLD is being impersonated in the subject + display name
(
// these are usually targeted with just 1 recipient,
// but sometimes they CC themselves or have a blank CC
length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2
and any(recipients.to,
// ensure that we're checking the org SLD
.email.domain.sld in $org_slds
and strings.icontains(subject.subject, .email.domain.sld)
and strings.icontains(sender.display_name, .email.domain.sld)
)
)
or (
// accounts for BCC'd messages where the recipients are empty
// if BCC, sometimes the recipient will be the attacker's email
length(recipients.to) + length(recipients.cc) + length(recipients.bcc) <= 2
and strings.icontains(subject.subject, mailbox.email.domain.sld)
and strings.icontains(sender.display_name, mailbox.email.domain.sld)
)
)
and (
// at least 1 link or non-image attachment
(
length(body.links) > 0
// these attacks all use compromosed senders, so we look for a domain
// that doesn't match the sender's domain to weed out legit messages
and any(body.links, .href_url.domain.root_domain != sender.email.domain.root_domain)
)
or length(filter(attachments, .file_type not in $file_types_images)) > 0
)
and not (
strings.contains(sender.display_name, "on behalf of")
and sender.email.domain.root_domain == "microsoftonline.com"
)
and all(recipients.to, .email.email != sender.email.email)
// 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
)
and (
(
profile.by_sender().prevalence in ("new", "outlier")
and not profile.by_sender().solicited
)
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_false_positives
)
)
and not profile.by_sender().any_false_positives
attack_types:
- "Credential Phishing"
tactics_and_techniques:
- "Social engineering"
detection_methods:
- "Header analysis"
- "Sender analysis"
id: "cb2b3ed3-268f-5753-9d2b-194d2ee1ed2e"
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,18 @@ source: |
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
)
attack_types:
- "Credential Phishing"
tactics_and_techniques:
Expand Down
2 changes: 1 addition & 1 deletion detection-rules/link_deactivated_bitly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ source: |
// link doesn't forward through
and beta.linkanalysis(.).effective_url.domain.domain == "bit.ly"
// blocked or gated by bit.ly
and strings.ilike(beta.linkanalysis(.).final_dom.display_text, "*link*blocked*", "*flagged*by*", "*been*deactivated*")
and strings.ilike(beta.linkanalysis(.).final_dom.display_text, "*link*blocked*", "*flagged*by*")
)
attack_types:
- "Credential Phishing"
Expand Down
23 changes: 17 additions & 6 deletions detection-rules/qr_code_suspicious_indicators.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,44 @@ source: |
// exclude images taken with mobile cameras and screenshots from android
and not any(.scan.exiftool.fields,
.key == "Model"
or .key == "Software" and strings.starts_with(.value, "Android")
or .key == "Software"
and strings.starts_with(.value, "Android")
)
// exclude images taken with mobile cameras and screenshots from Apple
and not any(.scan.exiftool.fields,
.key == "DeviceManufacturer" and .value == "Apple Computer Inc."
.key == "DeviceManufacturer"
and .value == "Apple Computer Inc."
)
)
)
or (
length(attachments) == 0
and any(file.explode(beta.message_screenshot()), .scan.qr.type is not null)
and any(file.explode(beta.message_screenshot()),
.scan.qr.type is not null and regex.contains(.scan.qr.data, '\.')
)
)
)
and (
any(recipients.to, strings.icontains(sender.display_name, .email.domain.sld))
any(recipients.to,
strings.icontains(sender.display_name, .email.domain.sld)
)
or length(body.current_thread.text) is null
or body.current_thread.text == ""
or regex.contains(subject.subject,
"(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)"
)
or (any(recipients.to, strings.icontains(subject.subject, .display_name)))
or (
(length(recipients.to) == 0 or all(recipients.to, .display_name == "Undisclosed recipients"))
(
length(recipients.to) == 0
or all(recipients.to, .display_name == "Undisclosed recipients")
)
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
)
or any(file.explode(beta.message_screenshot()), (.scan.qr.url.domain.tld in $suspicious_tlds))
or any(file.explode(beta.message_screenshot()),
(.scan.qr.url.domain.tld in $suspicious_tlds)
)
or any(attachments,
.file_type in $file_types_images
and any(file.explode(.), .scan.qr.url.domain.tld in $suspicious_tlds)
Expand Down
12 changes: 12 additions & 0 deletions insights/attachments/links_recipient_email.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: "Recipient email in attachment link"
type: "query"
source: |
filter(
map(attachments,
map(file.explode(.),
distinct(map(filter(.scan.url.urls, any(recipients.to, strings.icontains(..url, .email.email))), .url), .)
)
),
length(.) > 0
)
severity: "medium"

0 comments on commit 9f7cd81

Please sign in to comment.