EXPLORE
← Back to Explore
sublimelowRule

Spam: Attendee list solicitation

This rule detects messages claiming to have the attendee list from a specific event, they may list various information such as the number of contacts, the demographic and sample contacts. The messages typically offer to send pricing information upon request.

MITRE ATT&CK

Detection Query

type.inbound
and length(body.current_thread.text) < 2000
and length(body.links) < 5
and any(ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics,
        .name in ("Contact List Solicitation", "B2B Cold Outreach")
        and .confidence in ("medium", "high")
)
and (
  (
    (
      any([subject.subject, body.current_thread.text],
          (
            regex.icontains(.,
                            '(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Store|Grocer|Lead)(?:[[:punct:]]*s)?(?:\s\w*){0,9}(?:\blist(?:\b|[^ei])|database)'
            )
            and not (
              regex.icount(.,
                           '(email|contact)(?:[[:punct:]]*s)?(?:\s\w*){0,9}list'
              ) == 1
              and regex.icontains(.,
                                  '(?:unsub|remove|safe|delete|leave|update|part of|be added|safe)[[:punct:]]*s?(?:\s\w*){0,9}(mailing|email|my|sender)(?:\s\w*){0,9}list(?:\b|[^ei])',
                                  'email list(?:\b|[^ei])[[:punct:]]*s?(\s\w*){0,5}(?:unsub|remove|safe|delete|leave|up to date|part of|be added)'
              )
            )
          )
          or regex.icontains(.,
                             '\b(?:list|database)(?:[[:punct:]]*s)?\b(\s\w*){0,9}(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Store|Grocer)s?'
          )
      )
    )
    and (
      regex.icontains(body.current_thread.text,
                      "(?:interest(s|ed)|accessing|purchas|obtain|acuir|sample|provide.{0,10}samples|counts|pricing)"
      )
      or any(body.previous_threads,
             regex.icontains(.text,
                             "(?:interest(s|ed)|accessing|purchas|obtain|acuir|sample|provide.{0,10}samples|counts|pricing)"
             )
      )
    )
    and not regex.icontains(body.current_thread.text,
                            "(?:debit card|transaction.{0,20}processed)"
    )
  )
  // if there are indicators of a previous thread, also inspect the previous thread
  or (
    // contains references to the previous thread
    2 of (
      regex.icontains(body.current_thread.text, '(?:get|got|had) a chance'),
      regex.icontains(body.current_thread.text, '(take|move)(\Wthis)?\Wforward'),
      regex.icontains(body.current_thread.text,
                      '(review|drop me a line about) (my|this|it)'
      ),
      regex.icontains(body.current_thread.text, 'missed it( the)? first time'),
      regex.icontains(body.current_thread.text,
                      '(?:below|previous(ly)?|last|prior|earlier) (message|email|sent)'
      ),
      regex.icontains(body.current_thread.text,
                      // "the email I sent you earlier"
                      '(e?mail|message).{0,20}(sent).{0,20}(?:below|previous(ly)?|last|prior|earlier)'
      ),
      regex.icontains(body.current_thread.text,
                      '(sent).{0,50}(e?mail|message) (?:below|previous(ly)?|last|prior|earlier)'
      ),
      regex.icontains(body.current_thread.text, 'follow(?:ing)?(-| )up'),
      regex.icontains(body.current_thread.text, '(?:contact|attendee)s? list'),
      regex.icontains(body.current_thread.text, '(any|get an) update.{0,50}\?'),
      regex.icontains(body.current_thread.text, '(heard?|circling) back'),
      strings.icontains(body.current_thread.text, 'recently sent'),
      strings.icontains(body.current_thread.text, 'still interested'),
      regex.icontains(body.current_thread.text,
                      'did you (get|receive) (it|my (message|e?mail))'
      ),
      regex.icontains(body.current_thread.text, '(swift|quick|short) response'),
      regex.icontains(body.current_thread.text, 'kindly.{0,30}.interested'),
    )
    and any([body.html.display_text, body.plain.raw],
            (
              3 of (
                strings.icontains(., "from:"),
                strings.icontains(., "to:"),
                strings.icontains(., "sent:"),
                strings.icontains(., "date:"),
                strings.icontains(., "cc:"),
                strings.icontains(., "subject:"),
                strings.icontains(., "--Original Message--")
              )
              or strings.icontains(.,
                                   strings.concat(sender.display_name,
                                                  " <",
                                                  sender.email.email,
                                                  "> wrote:"
                                   )
              )
            )
            // match _after_ the previous thread indciators
            and (
              regex.icontains(.,
                              '(?:from|to|sent|date|cc|subject|wrote):(.|\W)*(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Mailing)(?:[[:punct:]]*s)?(?:\s\w*){0,9}(?:list(?:\b|[^ei])|database)'
              )
              or regex.icontains(.,
                                 '(?:from|to|sent|date|cc|subject|wrote):(.|\W)*(?:list(?:\b|[^ei])|database)(?:[[:punct:]]*s)?(\s\w*){0,9}(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Mailing)s?'
              )
              or (
                2 of (
                  strings.icontains(., "provide counts"),
                  regex.icontains(., "(?:verified|fresh) data"),
                  strings.icontains(., "precise targeting"),
                  strings.icontains(., "deliverability"),
                  regex.icontains(., "target (verticals|regions|criteria)")
                )
                and regex.icontains(., '(?:list(?:\b|[^ei])|database)')
              )
            )
    )
  )
)
// negate Zendesk support tickets
and not any(body.links,
            .href_url.domain.root_domain in ('zendesk.com')
            and .display_text == 'Zendesk'
)
and not profile.by_sender().solicited
and not profile.by_sender().any_messages_benign

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email

Tags

Attack surface reduction
Raw Content
name: "Spam: Attendee list solicitation"
description: "This rule detects messages claiming to have the attendee list from a specific event, they may list various information such as the number of contacts, the demographic and sample contacts. The messages typically offer to send pricing information upon request."
type: "rule"
severity: "low"
source: |
  type.inbound
  and length(body.current_thread.text) < 2000
  and length(body.links) < 5
  and any(ml.nlu_classifier(coalesce(body.html.display_text, body.plain.raw)).topics,
          .name in ("Contact List Solicitation", "B2B Cold Outreach")
          and .confidence in ("medium", "high")
  )
  and (
    (
      (
        any([subject.subject, body.current_thread.text],
            (
              regex.icontains(.,
                              '(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Store|Grocer|Lead)(?:[[:punct:]]*s)?(?:\s\w*){0,9}(?:\blist(?:\b|[^ei])|database)'
              )
              and not (
                regex.icount(.,
                             '(email|contact)(?:[[:punct:]]*s)?(?:\s\w*){0,9}list'
                ) == 1
                and regex.icontains(.,
                                    '(?:unsub|remove|safe|delete|leave|update|part of|be added|safe)[[:punct:]]*s?(?:\s\w*){0,9}(mailing|email|my|sender)(?:\s\w*){0,9}list(?:\b|[^ei])',
                                    'email list(?:\b|[^ei])[[:punct:]]*s?(\s\w*){0,5}(?:unsub|remove|safe|delete|leave|up to date|part of|be added)'
                )
              )
            )
            or regex.icontains(.,
                               '\b(?:list|database)(?:[[:punct:]]*s)?\b(\s\w*){0,9}(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Store|Grocer)s?'
            )
        )
      )
      and (
        regex.icontains(body.current_thread.text,
                        "(?:interest(s|ed)|accessing|purchas|obtain|acuir|sample|provide.{0,10}samples|counts|pricing)"
        )
        or any(body.previous_threads,
               regex.icontains(.text,
                               "(?:interest(s|ed)|accessing|purchas|obtain|acuir|sample|provide.{0,10}samples|counts|pricing)"
               )
        )
      )
      and not regex.icontains(body.current_thread.text,
                              "(?:debit card|transaction.{0,20}processed)"
      )
    )
    // if there are indicators of a previous thread, also inspect the previous thread
    or (
      // contains references to the previous thread
      2 of (
        regex.icontains(body.current_thread.text, '(?:get|got|had) a chance'),
        regex.icontains(body.current_thread.text, '(take|move)(\Wthis)?\Wforward'),
        regex.icontains(body.current_thread.text,
                        '(review|drop me a line about) (my|this|it)'
        ),
        regex.icontains(body.current_thread.text, 'missed it( the)? first time'),
        regex.icontains(body.current_thread.text,
                        '(?:below|previous(ly)?|last|prior|earlier) (message|email|sent)'
        ),
        regex.icontains(body.current_thread.text,
                        // "the email I sent you earlier"
                        '(e?mail|message).{0,20}(sent).{0,20}(?:below|previous(ly)?|last|prior|earlier)'
        ),
        regex.icontains(body.current_thread.text,
                        '(sent).{0,50}(e?mail|message) (?:below|previous(ly)?|last|prior|earlier)'
        ),
        regex.icontains(body.current_thread.text, 'follow(?:ing)?(-| )up'),
        regex.icontains(body.current_thread.text, '(?:contact|attendee)s? list'),
        regex.icontains(body.current_thread.text, '(any|get an) update.{0,50}\?'),
        regex.icontains(body.current_thread.text, '(heard?|circling) back'),
        strings.icontains(body.current_thread.text, 'recently sent'),
        strings.icontains(body.current_thread.text, 'still interested'),
        regex.icontains(body.current_thread.text,
                        'did you (get|receive) (it|my (message|e?mail))'
        ),
        regex.icontains(body.current_thread.text, '(swift|quick|short) response'),
        regex.icontains(body.current_thread.text, 'kindly.{0,30}.interested'),
      )
      and any([body.html.display_text, body.plain.raw],
              (
                3 of (
                  strings.icontains(., "from:"),
                  strings.icontains(., "to:"),
                  strings.icontains(., "sent:"),
                  strings.icontains(., "date:"),
                  strings.icontains(., "cc:"),
                  strings.icontains(., "subject:"),
                  strings.icontains(., "--Original Message--")
                )
                or strings.icontains(.,
                                     strings.concat(sender.display_name,
                                                    " <",
                                                    sender.email.email,
                                                    "> wrote:"
                                     )
                )
              )
              // match _after_ the previous thread indciators
              and (
                regex.icontains(.,
                                '(?:from|to|sent|date|cc|subject|wrote):(.|\W)*(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Mailing)(?:[[:punct:]]*s)?(?:\s\w*){0,9}(?:list(?:\b|[^ei])|database)'
                )
                or regex.icontains(.,
                                   '(?:from|to|sent|date|cc|subject|wrote):(.|\W)*(?:list(?:\b|[^ei])|database)(?:[[:punct:]]*s)?(\s\w*){0,9}(?:Attendee|Buyer|Contact|Decision Maker|Email|Member|Participant|Professional|Registrant|User|Visitor|Mailing)s?'
                )
                or (
                  2 of (
                    strings.icontains(., "provide counts"),
                    regex.icontains(., "(?:verified|fresh) data"),
                    strings.icontains(., "precise targeting"),
                    strings.icontains(., "deliverability"),
                    regex.icontains(., "target (verticals|regions|criteria)")
                  )
                  and regex.icontains(., '(?:list(?:\b|[^ei])|database)')
                )
              )
      )
    )
  )
  // negate Zendesk support tickets
  and not any(body.links,
              .href_url.domain.root_domain in ('zendesk.com')
              and .display_text == 'Zendesk'
  )
  and not profile.by_sender().solicited
  and not profile.by_sender().any_messages_benign

tags:
  - "Attack surface reduction"
attack_types:
  - "Spam"
detection_methods:
  - "Content analysis"
  - "Sender analysis"
id: "69715b62-7747-5f85-a399-dc72c3f8cb7d"