Scam: Piano giveaway

This rule is designed to identify and mitigate a specific type of fraudulent activity commonly targeted at educational institutions. This rule operates by analyzing incoming email content for certain characteristics indicative of a scam involving the offer of a free piano, often framed within the context of downsizing or a giveaway.

Sublime rule (View on GitHub)

  1name: "Scam: Piano giveaway"
  2description: "This rule is designed to identify and mitigate a specific type of fraudulent activity commonly targeted at educational institutions. This rule operates by analyzing incoming email content for certain characteristics indicative of a scam involving the offer of a free piano, often framed within the context of downsizing or a giveaway."
  3type: "rule"
  4severity: "medium"
  5source: |
  6  length(body.links) < 10
  7  and length(body.current_thread.text) < 1500
  8  and (
  9    // body detection
 10    // be sure to update the attachment detection regexes too!
 11    (
 12      (
 13        // items and brands
 14        // Guitars
 15        regex.icontains(body.current_thread.text,
 16                        '(?:Gibson|Fender|Lowden|Martin|Taylor|Ibanez)\s*[^\r\n]{0,50}\s*guitar',
 17                        'guitar\s*[^\r\n]{0,50}\s*(?:Gibson|Fender|Lowden|Martin|Taylor|Ibanez)',
 18        )
 19        // Piano/Keyboards
 20        or regex.icontains(body.current_thread.text,
 21                           '(?:Yamaha|Kawai|Baldwin|Roland|Stei?nway(?: (?:&|and) Sons?)?|\d{4})\s*[^\r\n]{0,50}(?:baby.grand|piano|baby.grand.piano|keyboard)',
 22                           // strong indicators for generalized instrument
 23                           '(?:piano|keyboard)\s*[^\r\n]{0,50}(?:available|sale|rehome|gift)'
 24        )
 25        // Violins & Orchestral 
 26        or regex.icontains(body.current_thread.text,
 27                           '(?:Stradivarius|Guarneri|Yamaha|Stentor|Eastman|Cremona|Cecilio|Mendini)\s*[^\r\n]{0,50}(violin|viola|cello|celli)',
 28        )
 29        // brass/wind/woodwinds
 30        or regex.icontains(body.current_thread.text,
 31                           '(?:Bach|Yamaha|Selmer|Conn|King|Jupiter|Buffet Crampon |Pearl)\s*[^\r\n]{0,50}(trombone|trumpet|saxophone|clarinet|flute)'
 32        )
 33  
 34        // generic
 35        or strings.ilike(body.current_thread.text,
 36                         '* musical instruments *',
 37                         '* instrument as a gift*'
 38        )
 39      )
 40      and (
 41        // often a person is moving
 42        strings.ilike(body.current_thread.text,
 43                      '* downsizing *',
 44                      '* relocating *',
 45                      '* relocation *',
 46                      '* moving *'
 47        )
 48        or strings.ilike(body.current_thread.text,
 49                         '* give away*',
 50                         '* generously offering *',
 51                         '*a loving home*',
 52                         '*a good home*',
 53                         '*find a new home *',
 54                         '*rehome these instruments *',
 55                         '* free donation*'
 56        )
 57        // generally someone died
 58        or regex.icontains(body.current_thread.text,
 59                           'inherited instruments',
 60                           'late (?:husband|father|dad|wife|mother|mom)',
 61                           '(?:husband|father|dad|wife|mother|mom)[^\r\n]{0,50}estate'
 62        )
 63        // passion/love for the item
 64        or strings.ilike(body.current_thread.text,
 65                         '* genuinely cherish*',
 66                         '* cherished possessions*',
 67                         '* passionate instrument*',
 68                         '* music lover*',
 69                         '* had a passion for music*',
 70                         '* appreciates music*',
 71                         "* special piece*",
 72                         "* a lot of meaning*",
 73                         "* profound sentimental*",
 74                         '* will cherish*'
 75        )
 76      )
 77      and (
 78        // it talks about a shipping fee upfront
 79        regex.icontains(body.current_thread.text,
 80                        'shipping (?:fee|cost|arrangement)',
 81                        '(?:responsible|pay) for shipping',
 82                        'no (?:local\s)?pick.?up',
 83                        'delivery only',
 84                        'moving company'
 85        )
 86        // recipient or someone they know might have an interest
 87        or strings.ilike(body.current_thread.text,
 88                         '* if you will take it *',
 89                         '* or have someone *',
 90                         '* indicate your interest *',
 91                         '* to someone you know *',
 92                         '* know someone who *',
 93                         '* someone you know would *',
 94                         '* someone who will *',
 95                         '* someone who truly *'
 96        )
 97        or regex.icontains(body.current_thread.text,
 98                           'if you[^\r\n]{0,20}(?:(?:might|will|would) be|are)[^\r\n]{0,20}interested',
 99                           '(?:any|some)one[^\r\n]{0,20}(is|will|would|might be)[^\r\n]{0,20}interested',
100                           'who (?:will|would|might) appreciate',
101        )
102        or (
103          // there's an email in the body 
104          regex.contains(body.current_thread.text,
105                         "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
106          )
107  
108          // and it's likely a freemail
109          and any($free_email_providers,
110                  strings.icontains(body.current_thread.text, .)
111          )
112        )
113        // reply-to doesn't match sender
114        or (
115          length(headers.reply_to) > 0
116          and sender.email.email not in map(headers.reply_to, .email.email)
117        )
118        // there are no recipients
119        or length(recipients.to) == 0
120        // redirects to a phone number
121        or regex.icontains(body.current_thread.text,
122                           '(?:call|contact|text)[^\r\n]{0,50} at'
123        )
124        or regex.icontains(body.current_thread.text,
125                           '(?:private|personal) (?:e-?)?mail'
126        )
127        or strings.icontains(body.current_thread.text, ' kindly ')
128      )
129    )
130    or (
131      any(filter(attachments, .size < 10000),
132          (
133            // items and brands
134            // Guitars
135            regex.icontains(file.parse_text(.).text,
136                            '(?:Gibson|Fender|Lowden|Martin|Taylor|Ibanez)\s*[^\r\n]{0,50}\s*guitar',
137                            'guitar\s*[^\r\n]{0,50}\s*(?:Gibson|Fender|Lowden|Martin|Taylor|Ibanez)',
138            )
139            // Piano/Keyboards
140            or regex.icontains(file.parse_text(.).text,
141                               '(?:Yamaha|Kawai|Baldwin|Roland|Stei?nway(?: (?:&|and) Sons?)?)\s*[^\r\n]{0,50}(?:baby.grand|piano|baby.grand.piano|keyboard)',
142                               // strong indicators for generalized instrument
143                               '(?:piano|keyboard)\s*[^\r\n]{0,50}(?:available|sale|rehome|gift)'
144            )
145            // Violins & Orchestral 
146            or regex.icontains(file.parse_text(.).text,
147                               '(?:Stradivarius|Guarneri|Yamaha|Stentor|Eastman|Cremona|Cecilio|Mendini)\s*[^\r\n]{0,50}(violin|viola|cello|celli)',
148            )
149            // brass/wind/woodwinds
150            or regex.icontains(file.parse_text(.).text,
151                               '(?:Bach|Yamaha|Selmer|Conn|King|Jupiter|Buffet Crampon |Pearl)\s*[^\r\n]{0,50}(trombone|trumpet|saxophone|clarinet|flute)'
152            )
153  
154            // generic
155            or strings.ilike(file.parse_text(.).text,
156                             '* musical instruments *',
157                             '* instrument as a gift*'
158            )
159          )
160          and (
161            // often a person is moving
162            strings.ilike(file.parse_text(.).text,
163                          '* downsizing *',
164                          '* relocating *',
165                          '* relocation *',
166                          '* moving *'
167            )
168            or strings.ilike(file.parse_text(.).text,
169                             '* give away*',
170                             '* generously offering *',
171                             '*a loving home*',
172                             '*a good home*',
173                             '*find a new home *',
174                             '*rehome these instruments *'
175            )
176            // generally someone died
177            or regex.icontains(file.parse_text(.).text,
178                               'inherited instruments',
179                               'late (?:husband|father|dad|wife|mother|mom)',
180                               '(?:husband|father|dad|wife|mother|mom)[^\r\n]{0,50}estate'
181            )
182            // passion/love for the item/music
183            or strings.ilike(file.parse_text(.).text,
184                             '* genuinely cherish*',
185                             '* cherished possessions*',
186                             '* passionate instrument*',
187                             '* music lover*',
188                             '* had a passion for music*',
189                             '* appreciates music*',
190                             "* special piece*",
191                             "* a lot of meaning*",
192                             "* profound sentimental*",
193                             '* will cherish*'
194            )
195          )
196          and (
197            // it talks about a shipping fee upfront
198            regex.icontains(file.parse_text(.).text,
199                            'shipping (?:fee|cost|arrangement)',
200                            '(?:responsible|pay) for shipping',
201                            'no (?:local\s)?pick.?up',
202                            'delivery only',
203                            'moving company'
204            )
205            or strings.ilike(file.parse_text(.).text,
206                             '* if you will take it *',
207                             '* or have someone *',
208                             '* indicate your interest *',
209                             '* to someone you know *',
210                             '* know someone who *',
211                             '* someone you know would *',
212                             '* someone who will *'
213            )
214            or regex.icontains(file.parse_text(.).text,
215                               'if you[^\r\n]{0,20}(?:(?:might|will|would) be|are)[^\r\n]{0,20}interested',
216                               '(?:any|some)one[^\r\n]{0,20}(is|will|would|might be)[^\r\n]{0,20}interested',
217                               'who (?:will|would|might) appreciate',
218            )
219            or (
220              // there's an email in the attachment 
221              regex.contains(file.parse_text(.).text,
222                             "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
223              )
224  
225              // and it's likely a freemail
226              and any($free_email_providers,
227                      strings.icontains(file.parse_text(..).text, .)
228              )
229            )
230            // reply-to doesn't match sender
231            or (
232              length(headers.reply_to) > 0
233              and sender.email.email not in map(headers.reply_to, .email.email)
234            )
235            // there are no recipients
236            or length(recipients.to) == 0
237            // redirects to a phone number
238            or regex.icontains(file.parse_text(.).text,
239                               '(?:call|contact|text)[^\r\n]{0,50} at'
240            )
241            or regex.icontains(file.parse_text(.).text,
242                               '(?:private|personal) (?:e-?)?mail'
243            )
244            or strings.icontains(file.parse_text(.).text, ' kindly ')
245          )
246      )
247    )
248  )
249  
250  // not high trust sender domains
251  and not (
252    sender.email.domain.root_domain in $high_trust_sender_root_domains
253    and headers.auth_summary.dmarc.pass
254  )
255  and not sender.email.domain.root_domain in (
256    'ridleyacademy.com', // person provides piano lessons and offers to give a Roland baby-grand away
257    'mountainpiano.com' // legitimate piano moving company in Denver 
258  )  
259
260attack_types:
261  - "BEC/Fraud"
262tactics_and_techniques:
263  - "Free email provider"
264detection_methods:
265  - "Content analysis"
266  - "Natural Language Understanding"
267  - "Sender analysis"
268id: "1a91a203-b1fe-52b7-9f71-cecdbf5cdce0"
to-top