Spam: Fake photo share

Message contains pretexting language about sharing photos ("found these photos and thought you'd like them", "remember these photos?") and a link with a newly registered domain. Fake threads and plain text bodies have been seen in the wild, indicating active evasion techniques.

Sublime rule (View on GitHub)

  1name: "Spam: Fake photo share"
  2description: 'Message contains pretexting language about sharing photos ("found these photos and thought you''d like them", "remember these photos?") and a link with a newly registered domain. Fake threads and plain text bodies have been seen in the wild, indicating active evasion techniques.'
  3type: "rule"
  4severity: "low"
  5source: |
  6  type.inbound
  7  and length(attachments) == 0
  8  and (
  9    (
 10      (
 11        (
 12          (length(body.plain.raw) < 500 and length(body.current_thread.text) == 0)
 13          or (
 14            length(body.html.display_text) < 500
 15            and length(body.current_thread.text) == 0
 16          )
 17          or (length(body.current_thread.text) < 500)
 18        )
 19        and strings.ilike(subject.subject,
 20                          "*picture*",
 21                          "*photo*",
 22                          "*image*",
 23                          "*sad news*",
 24                          "*sad announcement*",
 25                          "*sad update*",
 26                          "*new pics*"
 27        )
 28      )
 29      or (
 30        (
 31          (
 32            length(body.html.display_text) < 500
 33            and length(body.current_thread.text) == 0
 34          )
 35          and strings.ilike(body.html.display_text,
 36                            "*picture*",
 37                            "*photo*",
 38                            "*image*",
 39                            "*sad news*",
 40                            "*sad announcement*",
 41                            "*sad update*",
 42                            "*new pics*"
 43          )
 44        )
 45        or (
 46          (length(body.plain.raw) < 500 and length(body.current_thread.text) == 0)
 47          and strings.ilike(body.plain.raw,
 48                            "*picture*",
 49                            "*photo*",
 50                            "*image*",
 51                            "*sad news*",
 52                            "*sad announcement*",
 53                            "*sad update*",
 54                            "*new pics*"
 55          )
 56          and not strings.icontains(body.plain.raw, "[cid:image")
 57        )
 58        or (
 59          length(body.current_thread.text) < 500
 60          and strings.ilike(body.current_thread.text,
 61                            "*picture*",
 62                            "*photo*",
 63                            "*image*",
 64                            "*sad news*",
 65                            "*sad announcement*",
 66                            "*sad update*",
 67                            "*new pics*"
 68          )
 69        )
 70      )
 71      or (
 72        body.plain.raw is not null
 73        and body.html.display_text is null
 74        and (
 75          length(body.current_thread.text) == 0
 76          or (
 77            length(body.current_thread.text) < 500
 78            // fake forward indicator in the plain text body
 79            and (
 80              regex.contains(body.plain.raw,
 81                             'On (Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday).{0,50} wrote'
 82              )
 83              or strings.icontains(body.plain.raw, 'Original Message')
 84            )
 85            and not regex.contains(body.current_thread.text,
 86                                   'On (Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday).{0,50} wrote'
 87            )
 88            and not strings.icontains(body.current_thread.text,
 89                                      'Original Message'
 90            )
 91            and not any(headers.hops, any(.fields, .name == "Resent-From"))
 92          )
 93        )
 94        and strings.ilike(body.plain.raw,
 95                          "*picture*",
 96                          "*photo*",
 97                          "*image*",
 98                          "*sad news*",
 99                          "*sad announcement*",
100                          "*sad update*",
101                          "*pics*"
102        )
103        and not strings.istarts_with(body.plain.raw, "[cid:image")
104        and strings.icontains(subject.subject, sender.display_name)
105      )
106      or (
107        strings.icontains(subject.subject, sender.display_name)
108        and sender.email.domain.root_domain in $free_email_providers
109        and length(body.links) == 2
110        and length(filter(body.links, .display_text == "h")) == 1
111        and length(filter(body.links, .display_url.scheme == "ttp")) == 1
112      )
113    )
114    and length(body.links) < 5
115    and any(body.links,
116            (
117              (
118                network.whois(.href_url.domain).days_old < 30
119                or not network.whois(.href_url.domain).found
120                or network.whois(.href_url.domain).found is null
121              )
122              and .href_url.domain.root_domain != sender.email.domain.root_domain
123            )
124            or (
125              length(.display_text) == 1
126              and .href_url.domain.root_domain in ("facebook.com", "youtube.com")
127            )
128    )
129  )
130  and (
131    (
132      (
133        length(headers.references) > 0
134        or not any(headers.hops,
135                   any(.fields, strings.ilike(.name, "In-Reply-To"))
136        )
137      )
138      and not (
139        (
140          strings.istarts_with(subject.subject, "RE:")
141          or strings.istarts_with(subject.subject, "R:")
142          or strings.istarts_with(subject.subject, "ODG:")
143          or strings.istarts_with(subject.subject, "答复:")
144          or strings.istarts_with(subject.subject, "AW:")
145          or strings.istarts_with(subject.subject, "TR:")
146          or strings.istarts_with(subject.subject, "FWD:")
147          or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
148        )
149      )
150    )
151    or length(headers.references) == 0
152  )
153  // negate highly trusted sender domains unless they fail DMARC authentication
154  and (
155    (
156      sender.email.domain.root_domain in $high_trust_sender_root_domains
157      and not headers.auth_summary.dmarc.pass
158    )
159    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
160  )  
161attack_types:
162  - "Spam"
163tactics_and_techniques:
164  - "Evasion"
165  - "Social engineering"
166detection_methods:
167  - "Content analysis"
168  - "Sender analysis"
169  - "URL analysis"
170  - "Whois"
171id: "eb086f7d-3ad7-52cd-8e16-3ce08726b9ea"
to-top