Google presentation open redirect phishing
Detects emails containing links to Google Document Presentations that either have a single page with a single external link, have been removed for Terms of Service violations, or have been deleted.
Sublime rule (View on GitHub)
1name: "Google presentation open redirect phishing"
2description: "Detects emails containing links to Google Document Presentations that either have a single page with a single external link, have been removed for Terms of Service violations, or have been deleted."
3type: "rule"
4severity: "medium"
5source: |
6 type.inbound
7 and not strings.icontains(body.current_thread.text, 'invited you to edit')
8 and any(body.links,
9 // body link is to a google doc presentation
10 .href_url.domain.domain == "docs.google.com"
11 and strings.istarts_with(.href_url.path, '/presentation/')
12
13 // prefilter some to avoid clicking on _every_ google presentation link
14 and (
15 (
16 // make sure the display text is in the current thread and not a previous one.
17 strings.icontains(body.current_thread.text, .display_text)
18 // the display_text ends with a word that is 4-10 long
19 and regex.icontains(.display_text, '[[:punct:]\s][a-z0-9]{5,9}$')
20 // that word has to include a letter AND a number
21 and regex.icontains(.display_text,
22 '[[:punct:]\s](?:[a-z0-9]*[a-z][0-9][a-z0-9]*|[a-z0-9]*[0-9][a-z][a-z0-9]*)$'
23 )
24 and strings.iends_with(.href_url.path, '/pub')
25 )
26 or
27 // finally send the link to link analysis that presentation...
28 (
29 // contains a single link
30 length(filter(ml.link_analysis(., mode="aggressive").final_dom.links,
31 .href_url.domain.root_domain != "google.com"
32 )
33 ) == 1
34
35 // cannot be edited via link provided
36 and strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
37 'canEdit: false'
38 )
39
40 // and a single page
41 and strings.contains(ml.link_analysis(., mode="aggressive").final_dom.raw,
42 'slidePageCount: 1.0'
43 )
44
45 // where we have links which have been written via a google open redirect
46 and any(ml.link_analysis(., mode="aggressive").final_dom.links,
47 // links are not in thhe org_domains
48 .href_url.domain.domain not in $org_domains
49 and (
50 (
51 // don't include high rep domains
52 .href_url.domain.domain not in $tranco_1m
53 and .href_url.domain.domain not in $umbrella_1m
54 )
55 // if it's in Tranco or Umbrella, still include it if it's one of these
56 or .href_url.domain.domain in $free_file_hosts
57 or .href_url.domain.root_domain in $free_file_hosts
58 or .href_url.domain.root_domain in $free_subdomain_hosts
59 // or it's a url shortner
60 or .href_url.domain.root_domain in $url_shorteners
61 or .href_url.domain.root_domain in $social_landing_hosts
62 )
63 // which have been "unrolled" by the google_open_redirect rule
64 and any(.href_url.rewrite.encoders,
65 . == "google_open_redirect"
66 )
67 )
68 )
69 // or the presentation has been removed for violation of terms of service
70 or strings.icontains(ml.link_analysis(., mode="aggressive").final_dom.display_text,
71 "We're sorry. You can't access this item because it is in violation of our Terms of Service."
72 )
73 )
74 )
75 // when the sender is not google, the sender should not be a common prevalence
76 and (
77 ( // the message is not from google actual
78 sender.email.email not in (
79 'comments-noreply@docs.google.com',
80 'drive-shares-dm-noreply@google.com',
81 'drive-shares-noreply@google.com',
82 'calendar-notification@google.com'
83 )
84 // ensure the sender prevalence is not common
85 and profile.by_sender().prevalence != "common"
86 )
87 // or the message is from google actual
88 or (
89 sender.email.email in (
90 'comments-noreply@docs.google.com',
91 'drive-shares-dm-noreply@google.com',
92 'drive-shares-noreply@google.com',
93 'calendar-notification@google.com'
94 )
95 )
96 )
97
98 // not where the sender display name of the message is within org_display_names
99 and not (
100 // the message is from google actual
101 sender.email.email in (
102 'comments-noreply@docs.google.com',
103 'drive-shares-dm-noreply@google.com',
104 'drive-shares-noreply@google.com',
105 'calendar-notification@google.com'
106 )
107 and headers.auth_summary.dmarc.pass
108
109 // but the sender display name is within org_display_names
110 and any($org_display_names,
111 strings.istarts_with(sender.display_name,
112 strings.concat(., " (via Google ")
113 )
114 or strings.istarts_with(sender.display_name,
115 strings.concat(., " (Google ")
116 )
117 )
118 )
119 // negate highly trusted sender domains unless they fail DMARC authentication
120 // but ignore high_trust if the sender is one of the google actual senders
121 and (
122 (
123 (
124 sender.email.domain.root_domain in $high_trust_sender_root_domains
125 and not headers.auth_summary.dmarc.pass
126 )
127 or (
128 sender.email.domain.root_domain in $high_trust_sender_root_domains
129 and sender.email.email in (
130 'comments-noreply@docs.google.com',
131 'drive-shares-dm-noreply@google.com',
132 'drive-shares-noreply@google.com',
133 'calendar-notification@google.com'
134 )
135 )
136 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
137 )
138 )
139attack_types:
140 - "Credential Phishing"
141tactics_and_techniques:
142 - "Evasion"
143 - "Open redirect"
144 - "Social engineering"
145detection_methods:
146 - "URL analysis"
147 - "HTML analysis"
148id: "5d01ee3a-9426-5a8b-bde3-328d6780af6f"