Skip to content

Commit

Permalink
Signals: Collection of sender, header, content, and link-based signals (
Browse files Browse the repository at this point in the history
  • Loading branch information
bfilar authored Oct 6, 2023
1 parent 46a0b49 commit 32cb236
Show file tree
Hide file tree
Showing 27 changed files with 141 additions and 0 deletions.
4 changes: 4 additions & 0 deletions signals/attachments/attachment_file_name_rfq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Attachment: Contains RFQ File Name"
type: "query"
source: |
any(attachments, regex.icontains(.file_name, "(purchase.?order|Quot(e|ation))"))
4 changes: 4 additions & 0 deletions signals/content/body_contains_btc_wallet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Body: Bitcoin address"
type: "query"
source: |
any([body.plain.raw, body.html.display_text], regex.contains(., '\b[13]{1}[a-km-zA-HJ-NP-Z1-9]{25,34}\b'))
6 changes: 6 additions & 0 deletions signals/content/body_contains_emoji.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: "Body: Contains Emoji"
type: "query"
source: |
regex.contains(body.plain.raw,
'[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]'
)
4 changes: 4 additions & 0 deletions signals/content/body_contains_recipient_email.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Body: Contains Recipient Email"
type: "query"
source: |
any(recipients.to, strings.icontains(body.current_thread.text, .email.email))
7 changes: 7 additions & 0 deletions signals/content/body_contains_recipient_local_part.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: "Body: Contains Recipient Local Part"
type: "query"
source: |
any(recipients.to,
strings.icontains(body.current_thread.text, .email.local_part) and not
strings.icontains(body.current_thread.text, .email.email)
)
8 changes: 8 additions & 0 deletions signals/content/body_contains_rfq_language.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: "Body: Contains RFQ Language"
type: "query"
source: |
1 of (
(regex.icontains(body.current_thread.text, '(discuss.{0,15}purchas(e|ing))')),
(regex.icontains(body.current_thread.text, '(sign(ed?)|view).{0,10}(purchase order)|Request for a Quot(e|ation)')),
(regex.icontains(body.current_thread.text, '(please|kindly).{0,30}quote'))
)
4 changes: 4 additions & 0 deletions signals/content/body_contains_vm_language.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Body: Contains Voicemail Language"
type: "query"
source: |
regex.contains(body.current_thread.text, '(voice)\s?(mail|message|recording|call)')
4 changes: 4 additions & 0 deletions signals/content/body_excessive_space.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Body: Space Obfuscation"
type: "query"
source: |
regex.icontains(coalesce(body.html.inner_text, body.html.display_text), '([a-zA-Z\d\.]\s){30,}')
4 changes: 4 additions & 0 deletions signals/content/body_length.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Content: Body Length"
type: "query"
source: |
length(body.current_thread.text)
6 changes: 6 additions & 0 deletions signals/content/subject_contains_auth_language.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: "Subject: Contains Authentication Language"
type: "query"
source: |
regex.contains(subject.subject,
"(Authenticat(e|or|ion)|2fa|Multi.Factor|(qr|bar).code|action.require|alert|Att(n|ention):)"
)
6 changes: 6 additions & 0 deletions signals/content/subject_contains_emoji.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: "Subject: Contains Emoji"
type: "query"
source: |
regex.contains(subject.subject,
'[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{1F700}-\x{1F77F}\x{1F780}-\x{1F7FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{2300}-\x{23FF}]'
)
4 changes: 4 additions & 0 deletions signals/content/subject_contains_recipient_sld.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Subject: Contains Recipient SLD"
type: "query"
source: |
any(recipients.to, strings.icontains(subject.subject, .email.domain.sld))
4 changes: 4 additions & 0 deletions signals/content/subject_contains_rfq_language.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Subject: Contains RFQ Language"
type: "query"
source: |
regex.icontains(subject.subject, '(request for (purchase|quot(e|ation))|\bRFQ\b|\bRFP\b)')
4 changes: 4 additions & 0 deletions signals/content/subject_contains_vm_language.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Subject: Contains Voicemail Language"
type: "query"
source: |
regex.icontains(subject.subject, 'voice.*?(mail|message|recording|call)')
6 changes: 6 additions & 0 deletions signals/headers/headers_all_recipients_bcc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: "Headers: All recipients BCCd"
type: "query"
source: |
length(recipients.to) == 0
and length(recipients.cc) == 0
and length(recipients.bcc) == 1
12 changes: 12 additions & 0 deletions signals/headers/headers_replyto_similar_to_sender.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: "Headers: Reply-to Domain Similar To Sender Domain"
type: "query"
source: |
any(headers.reply_to,
length(headers.reply_to) > 0
and all(headers.reply_to,
(
strings.ilevenshtein(.email.domain.root_domain, sender.email.domain.root_domain) <= 1
and .email.domain.root_domain != sender.email.domain.root_domain
)
)
)
5 changes: 5 additions & 0 deletions signals/links/link_contains_recipient_email.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: "Link: Contains Recipient Email"
type: "query"
source: |
any(body.links, any(recipients.to, strings.icontains(..href_url.query_params, .email.email)))
4 changes: 4 additions & 0 deletions signals/sender/sender_display_contains_honorific.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Sender: Display Name Contains Honorific"
type: "query"
source: |
regex.icontains(sender.display_name, "(?:Mr.?|Mrs.?|Ms.?|Miss.?|Dr.?|Prof.?|Sir.?|Lady.?|Rev.?)[ \t]+")
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: "Sender: Display Name Contains Recipient Local-Part"
type: "query"
source: |
any(recipients.to, strings.icontains(sender.display_name, .email.local_part))
and not any(recipients.to, strings.icontains(.display_name, "recipients"))
4 changes: 4 additions & 0 deletions signals/sender/sender_display_contains_vm_language.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Sender: Display Name Contains Voicemail Language"
type: "query"
source: |
regex.icontains(sender.display_name, 'voice.*?(mail|message|recording|call)')
4 changes: 4 additions & 0 deletions signals/sender/sender_display_is_upper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Sender: Display Name Contains All Capital Letters"
type: "query"
source: |
regex.match(sender.display_name, "^[^a-z]*[A-Z][^a-z]*$")
4 changes: 4 additions & 0 deletions signals/sender/sender_display_name_contains_via.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Sender: Display Name Contains All Capital Letters"
type: "query"
source: |
regex.icontains(sender.display_name, "(?:^|[^a-zA-Z0-9])via(?:$|[^a-zA-Z0-9])|[\"']via[\"']")
4 changes: 4 additions & 0 deletions signals/sender/sender_domain_not_in_tranco10k.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Sender: Domain not in Tranco 10k"
type: "query"
source: |
sender.email.domain.domain not in $tranco_10k
4 changes: 4 additions & 0 deletions signals/sender/sender_domain_not_in_tranco1m.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Sender: Domain not in Tranco 1m"
type: "query"
source: |
sender.email.domain.domain not in $tranco_1m
9 changes: 9 additions & 0 deletions signals/sender/sender_domain_similar_to_recipient_domain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: "Sender: Domain Similar To Recipient Domain"
type: "query"
source: |
any(recipients.to,
(
strings.ilevenshtein(.email.email, sender.email.email) <= 1 and
.email.email != sender.email.email
)
)
7 changes: 7 additions & 0 deletions signals/sender/sender_email_mismatched_from_and_reply-to.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: "Sender: Mismatched From and Reply-to Email"
type: "query"
source: |
any(headers.reply_to,
length(headers.reply_to) > 0
and all(headers.reply_to, .email.email != sender.email.email)
)
4 changes: 4 additions & 0 deletions signals/sender/sender_length_local_part.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "Sender: Local-Part Length"
type: "query"
source: |
length(sender.email.local_part)

0 comments on commit 32cb236

Please sign in to comment.