-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update impersonation_sharepoint_fake_file_share.yml by @zoomequipd #2265 Source SHA a23280b Triggered by @zoomequipd
- Loading branch information
Sublime Rule Testing Bot
committed
Jan 6, 2025
1 parent
63d3713
commit 7bef928
Showing
1 changed file
with
20 additions
and
0 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
detection-rules/impersonation_sharepoint_fake_file_share.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: "Brand impersonation: Sharepoint fake file share" | ||
description: | | ||
This rule detects messages impersonating a Sharepoint file sharing email where no links point to known Microsoft domains. | ||
type: "rule" | ||
severity: "medium" | ||
source: "type.inbound\n\n// Sharepoint body content looks like this\nand (\n (\n (\n any([body.current_thread.text, body.plain.raw],\n strings.ilike(.,\n \"*shared a file with you*\",\n \"*shared with you*\",\n \"*invited you to access a file*\",\n \"*received a document*\",\n \"*shared a document*\",\n \"*shared this document*\"\n )\n )\n or any(file.explode(beta.message_screenshot()),\n strings.ilike(.scan.ocr.raw,\n \"*shared a file with you*\",\n \"*shared with you*\",\n \"*invited you to access a file*\",\n \"*received a document*\",\n \"*shared a document*\",\n \"*shared this document*\"\n )\n )\n )\n and (\n strings.ilike(subject.subject,\n \"*shared*\",\n \"*updated*\",\n \"*sign*\",\n \"*review*\"\n )\n or strings.ilike(subject.subject,\n \"*Excel*\",\n \"*SharePoint*\",\n \"*PowerPoint*\",\n \"*OneNote*\"\n )\n or any(body.links, strings.icontains(.display_text, \"OPEN DOCUMENT\"))\n or subject.subject is null\n or subject.subject == \"\"\n // the org as determined by NLU is in the subject\n or any(ml.nlu_classifier(body.current_thread.text).entities,\n .name == \"org\" and strings.icontains(subject.subject, .text)\n )\n \n )\n )\n or any([\n \"Contigo\", // Spanish\n \"Avec vous\", // French\n \"Mit Ihnen\", // German\n \"Con te\", // Italian\n \"Com você\", // Portuguese\n \"Met u\", // Dutch\n \"С вами\", // Russian\n \"与你\", // Chinese (Simplified)\n \"與您\", // Chinese (Traditional)\n \"あなたと\", // Japanese\n \"당신과\", // Korean\n \"معك\", // Arabic\n \"آپ کے ساتھ\", // Urdu\n \"আপনার সাথে\", // Bengali\n \"आपके साथ\", // Hindi\n \"Sizinle\", // Turkish // Azerbaijani\n \"Med dig\", // Swedish\n \"Z tobą\", // Polish\n \"З вами\", // Ukrainian\n \"Önnel\", // Hungarian\n \"Μαζί σας\", // Greek\n \"איתך\", // Hebrew\n \"กับคุณ\", // Thai\n \"Với bạn\", // Vietnamese\n \"Dengan Anda\", // Indonesian // Malay\n \"Nawe\", // Swahili\n \"Cu dumneavoastră\", // Romanian\n \"S vámi\", // Czech\n \"Med deg\", // Norwegian\n \"S vami\", // Slovak\n \"Med dig\", // Danish\n \"Amb vostè\", // Catalan\n \"Teiega\", // Estonian\n \"S vama\", // Serbian\n ],\n strings.icontains(subject.subject, .)\n )\n)\n\n// contains logic that impersonates Microsoft\nand (\n any(ml.logo_detect(beta.message_screenshot()).brands,\n strings.starts_with(.name, \"Microsoft\")\n )\n or any(attachments,\n .file_type in $file_types_images\n and any(ml.logo_detect(.).brands,\n strings.starts_with(.name, \"Microsoft\")\n )\n )\n or (\n regex.icontains(body.html.raw,\n '<table[^>]*>\\s*<tbody[^>]*>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor=\"#[0-9A-Fa-f]{6}\"[^>]*>\\s* \\s*</td>\\s*){2}\\s*</tr>\\s*<tr[^>]*>\\s*(<td[^>]*bgcolor=\"#[0-9A-Fa-f]{6}\"[^>]*>\\s* \\s*</td>\\s*){2}'\n )\n or 3 of (\n regex.icontains(body.html.raw, '.password-expiration'),\n regex.icontains(body.html.raw, 'color: #2672ec;'),\n regex.icontains(body.html.raw, 'Microsoft')\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(246,\\s?93,\\s?53\\)'),\n regex.icontains(body.html.raw, 'rgb\\(129,\\s?187,\\s?5\\)'),\n regex.icontains(body.html.raw, 'rgb\\(4,\\s?165,\\s?240\\)'),\n regex.icontains(body.html.raw, 'rgb\\(255,\\s?186,\\s?7\\)'),\n )\n or 4 of (\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)red'\n ),\n regex.icontains(body.html.raw, 'rgb\\(19,\\s?186,\\s?132\\)'),\n regex.icontains(body.html.raw, 'rgb\\(4,\\s?166,\\s?240\\)'),\n regex.icontains(body.html.raw, 'rgb\\(255,\\s?186,\\s?8\\)'),\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(245,\\s?189,\\s?67\\)'),\n regex.icontains(body.html.raw, 'rgb\\(137,\\s?184,\\s?57\\)'),\n regex.icontains(body.html.raw, 'rgb\\(217,\\s?83,\\s?51\\)'),\n regex.icontains(body.html.raw, 'rgb\\(71,\\s?160,\\s?218\\)')\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(73,\\s?161,\\s?232\\)'),\n regex.icontains(body.html.raw, 'rgb\\(224,\\s?92,\\s?53\\)'),\n regex.icontains(body.html.raw, 'rgb\\(139,\\s?183,\\s?55\\)'),\n regex.icontains(body.html.raw, 'rgb\\(244,\\s?188,\\s?65\\)')\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(213,\\s?56,\\s?62\\)'),\n regex.icontains(body.html.raw, 'rgb\\(0,\\s?114,\\s?30\\)'),\n regex.icontains(body.html.raw, 'rgb\\(0,\\s?110,\\s?173\\)'),\n regex.icontains(body.html.raw, 'rgb\\(227,\\s?209,\\s?43\\)'),\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(246,\\s?93,\\s?53\\)'),\n regex.icontains(body.html.raw, 'rgb\\(129,\\s?187,\\s?5\\)'),\n regex.icontains(body.html.raw, 'rgb\\(4,\\s?165,\\s?240\\)'),\n regex.icontains(body.html.raw, 'rgb\\(255,\\s?186,\\s?7\\)')\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(242,\\s?80,\\s?34\\)'),\n regex.icontains(body.html.raw, 'rgb\\(127,\\s?186,\\s?0\\)'),\n regex.icontains(body.html.raw, 'rgb\\(0,\\s?164,\\s?239\\)'),\n regex.icontains(body.html.raw, 'rgb\\(255,\\s?185,\\s?0\\)'),\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(243,\\s?83,\\s?37\\)'),\n regex.icontains(body.html.raw, 'rgb\\(129,\\s?188,\\s?6\\)'),\n regex.icontains(body.html.raw, 'rgb\\(5,\\s?166,\\s?240\\)'),\n regex.icontains(body.html.raw, 'rgb\\(255,\\s?186,\\s?8\\)')\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\(243,\\s?80,\\s?34\\)'),\n regex.icontains(body.html.raw, 'rgb\\(128,\\s?187,\\s?3\\)'),\n regex.icontains(body.html.raw, 'rgb\\(3,\\s?165,\\s?240\\)'),\n regex.icontains(body.html.raw, 'rgb\\(255,\\s?185,\\s?3\\)')\n )\n or 4 of (\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?(#)?(FF1940|eb5024|F25022|FF1941|red)'\n ),\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?(#)?(36ba57|3eb55d|7db606|7FBA00|36ba58|green)'\n ),\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?#(04a1d6|04B5F0|05a1e8|00A4EF|01a4ef|04a5f0)'\n ),\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?#(FFCA07|f7b408|FFB900|FFCA08|ffb901|ffba07)'\n ),\n )\n or 4 of (\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?#(f65314|f65d35|49a1e8|E74F23|F35325)'\n ),\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?#(7cbf42|81bb05|e05c35|7AB206|81BC06)'\n ),\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?#(00a4ef|0078d7|8bb737|04a5f0|059EE4|05A6F0)'\n ),\n regex.icontains(body.html.raw,\n '(background-color:|background:|bgcolor=)(.)?#(ffb900|ffba07|f4bc41|F2B108|FFBA08)'\n ),\n )\n // fuzzy approach\n or 4 of (\n regex.icontains(body.html.raw,\n 'rgb\\((2[1-4][0-9]|250),\\s?(7[0-9]|8[0-9]|9[0-3]),\\s?(3[0-9]|4[0-9]|5[0-3])\\)'\n ),\n regex.icontains(body.html.raw,\n 'rgb\\((12[0-9]|13[0-9]),\\s?(18[0-9]|190),\\s?([0-9]|10)\\)'\n ),\n regex.icontains(body.html.raw,\n 'rgb\\(([0-9]|1[0-5]),\\s?(16[0-5]|166),\\s?(23[0-9]|240)\\)'\n ),\n regex.icontains(body.html.raw,\n 'rgb\\((25[0-5]),\\s?(18[5-9]|19[0-9]),\\s?([0-9]|10)\\)'\n )\n )\n or 4 of (\n regex.icontains(body.html.raw, 'rgb\\((25[0-5]),\\s?(2[0-5]),\\s?(6[0-4])\\)'),\n regex.icontains(body.html.raw, 'rgb\\((6[0-2]),\\s?(18[0-1]),\\s?(9[0-3])\\)'),\n regex.icontains(body.html.raw, 'rgb\\(([0-4]),\\s?(18[0-1]),\\s?(24[0])\\)'),\n regex.icontains(body.html.raw, 'rgb\\((25[0-5]),\\s?(20[0-2]),\\s?([0-7])\\)')\n )\n or regex.icontains(body.html.raw,\n '<a[^>]+style=\"[^\"]*background-color:\\s*#[0-9A-F]{2}[5-9A-F]{2}[0-9A-F]{2}[^\"]*\"[^>]*>[^<]*(?:open)[^<]*</a>' // blue button containing the word \"open\"\n )\n or (\n any(recipients.to,\n strings.icontains(body.current_thread.text,\n strings.concat(.email.domain.sld,\n \" shared a file with you\"\n )\n )\n )\n )\n )\n)\n\n// Negate messages when the message-id indciates the message is from MS actual. DKIM/SPF domains can be custom and therefore are unpredictable.\nand not (\n strings.starts_with(headers.message_id, '<Share-')\n and strings.ends_with(headers.message_id, '@odspnotify>')\n)\n\n// fake Sharepoint shares are easy to identify if there are any links\n// that don't point to microsoft[.]com or *.sharepoint[.]com\nand not all(body.links,\n .href_url.domain.root_domain in (\n \"1drv.ms\",\n \"aka.ms\",\n \"microsoft.com\",\n \"sharepoint.com\"\n )\n)\nand sender.email.domain.root_domain not in $org_domains\nand sender.email.domain.root_domain not in (\n \"bing.com\",\n \"microsoft.com\",\n \"microsoftonline.com\",\n \"microsoftsupport.com\",\n \"microsoft365.com\",\n \"office.com\",\n \"onedrive.com\",\n \"sharepointonline.com\",\n \"yammer.com\",\n // ignore microsoft privacy statement links\n \"aka.ms\"\n)\n\n// negate highly trusted sender domains unless they fail DMARC authentication\nand (\n (\n sender.email.domain.root_domain in $high_trust_sender_root_domains\n and not headers.auth_summary.dmarc.pass\n )\n or sender.email.domain.root_domain not in $high_trust_sender_root_domains\n)\n// and (\n// profile.by_sender().solicited == false\n// or profile.by_sender_email().prevalence == \"new\"\n// or (\n// profile.by_sender().any_messages_malicious_or_spam\n// and not profile.by_sender().any_false_positives\n// )\n// )\n// and not profile.by_sender().any_false_positives\n" | ||
attack_types: | ||
- "Credential Phishing" | ||
- "Malware/Ransomware" | ||
detection_methods: | ||
- "Content analysis" | ||
- "Header analysis" | ||
- "URL analysis" | ||
- "Computer Vision" | ||
tactics_and_techniques: | ||
- "Impersonation: Brand" | ||
- "Social engineering" | ||
id: "ff8b296b-aa0d-5df0-b4d2-0e599b688f6a" | ||
testing_pr: 2265 | ||
testing_sha: a23280bfe254e7a7ea5ceeaf2504bc4ea19993da |