EXPLORE
← Back to Explore
sublimelowRule

Current event: CrowdStrike impersonation

Discovery rule for messages which are leveraging the CrowdStrike defect generated on Jul 19th 2024 which caused wide spread outages.

MITRE ATT&CK

initial-access

Detection Query

type.inbound
and (
  any([
        sender.display_name,
        subject.subject,
        sender.email.email,
        body.current_thread.text
      ],
      strings.icontains(., "crowdstrike", )
      or (strings.icontains(., "crowd") and strings.icontains(., "falcon"))
  )
  or any(body.links,
         strings.icontains(.display_text, 'crowdstrike')
         or (
           strings.icontains(.display_text, "crowd")
           and strings.icontains(.display_text, "falcon")
         )
  )
  // look alike display_name
  or 0 < strings.ilevenshtein(strings.replace_confusables(sender.display_name), 'crowdstrike') <= 2
  or 0 <= strings.ilevenshtein(strings.replace_confusables(sender.display_name), 'crowdfalcon') <= 2

  // look alike domains
  or 0 < strings.ilevenshtein(strings.replace_confusables(sender.email.domain.sld), 'crowdstrike') <= 2
  or 0 <= strings.ilevenshtein(strings.replace_confusables(sender.email.domain.sld), 'crowdfalcon') <= 2
)

// has either attachments or links
and sum([length(body.links), length(attachments)]) > 0

// the links don't all go to crowdstrike or other "trusted" sites.
and not all(body.links,
        .href_url.domain.root_domain in (
          'crowdstrike.com',
          'aka.ms',
          'mimecastprotect.com',
          'mimecast.com',
          'microsoft.com'
        )
)

// not from CS actual
and not (
  sender.email.domain.root_domain == 'crowdstrike.com'
  and headers.auth_summary.dmarc.pass
  and headers.auth_summary.spf.pass
  and (
    // if there is a reply-to header, make sure the root_domain is crowdstrike
    (
      length(headers.reply_to) > 0
      and all(headers.reply_to, .email.domain.root_domain == 'crowdstrike.com')
    )
    // if there isn't a reply-to, that's ok too
    or length(headers.reply_to) == 0
  )
  // return_path root_domain must be crowstrike.com
  and headers.return_path.domain.root_domain == 'crowdstrike.com'
)

// contains themed words based on Crowdstrikes Recommendations
and (
  // safe mode
  strings.icontains(subject.subject, 'safe mode')
  or any(body.links, strings.icontains(.display_text, 'safe mode'))
  or strings.icontains(body.current_thread.text, 'safe mode')

  // windows recovery
  or strings.icontains(subject.subject, 'windows recovery')
  or any(body.links, strings.icontains(.display_text, 'windows recovery'))
  or strings.icontains(body.current_thread.text, 'windows recovery')

  // file name
  or strings.icontains(subject.subject, 'C-00000291')
  or any(body.links, strings.icontains(.display_text, 'C-00000291'))
  or strings.icontains(body.current_thread.text, 'C-00000291')

  // the body contains keywords and the link is sus
  or (
    any([body.current_thread.text, body.html.display_text, body.plain.raw],
        2 of (
          strings.icontains(., 'outage'),
          strings.icontains(., 'Update'),
          strings.icontains(., 'IT Issues'),
          strings.icontains(., 'Download'),
          strings.icontains(., 'Fix'),
          strings.icontains(., "password"),
          strings.icontains(., "unread messages"),
          strings.icontains(., "Shared Documents"),
          strings.icontains(., "expiration"),
          strings.icontains(., "office"),
          strings.icontains(., "expire"),
          strings.icontains(., "expiring"),
          strings.icontains(., "kindly"),
          strings.icontains(., "renew"),
          strings.icontains(., "review"),
          strings.icontains(., "emails failed"),
          strings.icontains(., "kicked out"),
          strings.icontains(., "prevented"),
          strings.icontains(., "storage quota"),
          strings.icontains(., "required now"),
          strings.icontains(., "cache"),
          strings.icontains(., "qr code"),
          strings.icontains(., "barcode"),
          strings.icontains(., "security update"),
          strings.icontains(., "quarantine")
        )
    )
    and any(body.links,
            // is sus
            .href_url.domain.domain in $url_shorteners
            or .href_url.domain.domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_subdomain_hosts
            // contains a an open redirect rewriter
            or any(.href_url.rewrite.encoders,
                   strings.icontains(., "open_redirect")
            )
            // contains signs of an open redirect
            or strings.icontains(.href_url.path, 'http')
            or strings.icontains(.href_url.path, '//')
            or strings.icontains(.href_url.path, '%2f%2f')
            or strings.icontains(.href_url.query_params, 'http')
            or strings.icontains(.href_url.query_params, '//')
    )
  )

  // body link domains contain crowdstrike and are newly registered
  or (
    any(body.links,
        // the domain is newly registered
        (
          (
            strings.icontains(.href_url.domain.domain, 'crowdstrike')
            or (
              strings.icontains(.href_url.domain.domain, "crowd")
              and strings.icontains(.href_url.domain.domain, "falcon")
            )
          )
          // and it's a newly registered domain
          and network.whois(.href_url.domain).days_old <= 14
        )
        // the path
        or (
          (
            strings.icontains(.href_url.path, 'crowdstrike')
            or (
              strings.icontains(.href_url.path, "crowd")
              and strings.icontains(.href_url.path, "falcon")
            )
          )
          // the path has keywords, but the domain is not high-rep
          and (
            (
              .href_url.domain.domain not in $tranco_1m
              and .href_url.domain.domain not in $umbrella_1m
            )
            // if it's in Tranco or Umbrella, still include it if it's one of these
            or .href_url.domain.domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_file_hosts
            or .href_url.domain.root_domain in $free_subdomain_hosts
          )
        )
    )
  )

  // Attachments contain links
  or (
    any(attachments,
        // Attachment file names
        strings.icontains(.file_name, 'crowdstrike')
        or (
          strings.icontains(.file_name, "crowd")
          and strings.icontains(.file_name, "falcon")
        )
        // attachment names inside of a zip
        or (
          .file_extension in~ $file_extensions_common_archives
          // explode the attachment and look at the filename
          and any(file.explode(.),
                  .depth == 1
                  and (
                    strings.icontains(.file_name, 'crowdstrike')
                    or (
                      strings.icontains(.file_name, "crowd")
                      and strings.icontains(.file_name, "falcon")
                    )
                  )
          )
        )
        // links in attachments
        or (
          any(file.explode(.),
              any(.scan.url.urls,

                  // the domain
                  (
                    (
                      strings.icontains(.domain.domain, 'crowdstrike')
                      or (
                        strings.icontains(.domain.domain, "crowd")
                        and strings.icontains(.domain.domain, "falcon")
                      )
                    )
                    // and it's a newly registered domain
                    and network.whois(.domain).days_old <= 14
                  )
                  // the path
                  or (
                    (
                      strings.icontains(.path, 'crowdstrike')
                      or (
                        strings.icontains(.path, "crowd")
                        and strings.icontains(.path, "falcon")
                      )
                    )
                    // the path has keywords, but the domain is not high-rep
                    and (
                      (
                        .domain.domain not in $tranco_1m
                        and .domain.domain not in $umbrella_1m
                      )
                      // if it's in Tranco or Umbrella, still include it if it's one of these
                      or .domain.domain in $free_file_hosts
                      or .domain.root_domain in $free_file_hosts
                      or .domain.root_domain in $free_subdomain_hosts
                    )
                  )

                  // or it's free file host/subdomain host
                  or .domain.domain in $free_file_hosts
                  or .domain.root_domain in $free_file_hosts
                  or .domain.root_domain in $free_subdomain_hosts

                  // LA for downloaded filenames
                  or any(ml.link_analysis(., mode="aggressive").files_downloaded,
                         (
                           strings.icontains(.file_name, 'crowdstrike')
                           or (
                             strings.icontains(.file_name, "crowd")
                             and strings.icontains(.file_name, "falcon")
                           )
                         // just an exe
                         )
                         or .file_extension in $file_extensions_executables
                         or (
                           .file_extension in~ $file_extensions_common_archives
                           // explode the attachment and look at the filename
                           and any(file.explode(.),
                                   .depth == 1
                                   and (
                                     strings.icontains(.file_name,
                                                       'crowdstrike'
                                     )
                                     or (
                                       strings.icontains(.file_name, "crowd")
                                       and strings.icontains(.file_name,
                                                             "falcon"
                                       )
                                     )
                                   )
                           )
                         )
                  )
              )
          )
        )
    )
  )
)
// not high trust sender domains
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not headers.auth_summary.dmarc.pass
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)

// and no false positives and not solicited
and (
  not profile.by_sender().any_false_positives
  and not profile.by_sender().solicited
)

// negate commonly benign conditions
and not (
  // contains a large number of links
  length(body.links) > 20
  or (
    // contains a few links, but also contains unsub options
    length(body.links) <= 7
    and (
      any(body.links,
          strings.icontains(.display_text, "unsub")
          or any(headers.hops, any(.fields, .name == "List-Unsubscribe"))
      )
    )
  )
)

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email
Raw Content
name: "Current event: CrowdStrike impersonation"
description: "Discovery rule for messages which are leveraging the CrowdStrike defect generated on Jul 19th 2024 which caused wide spread outages. "
type: "rule"
severity: "low"
references:
  - "https://www.crowdstrike.com/blog/statement-on-falcon-content-update-for-windows-hosts/"
source: |
  type.inbound
  and (
    any([
          sender.display_name,
          subject.subject,
          sender.email.email,
          body.current_thread.text
        ],
        strings.icontains(., "crowdstrike", )
        or (strings.icontains(., "crowd") and strings.icontains(., "falcon"))
    )
    or any(body.links,
           strings.icontains(.display_text, 'crowdstrike')
           or (
             strings.icontains(.display_text, "crowd")
             and strings.icontains(.display_text, "falcon")
           )
    )
    // look alike display_name
    or 0 < strings.ilevenshtein(strings.replace_confusables(sender.display_name), 'crowdstrike') <= 2
    or 0 <= strings.ilevenshtein(strings.replace_confusables(sender.display_name), 'crowdfalcon') <= 2
  
    // look alike domains
    or 0 < strings.ilevenshtein(strings.replace_confusables(sender.email.domain.sld), 'crowdstrike') <= 2
    or 0 <= strings.ilevenshtein(strings.replace_confusables(sender.email.domain.sld), 'crowdfalcon') <= 2
  )
  
  // has either attachments or links
  and sum([length(body.links), length(attachments)]) > 0
  
  // the links don't all go to crowdstrike or other "trusted" sites.
  and not all(body.links,
          .href_url.domain.root_domain in (
            'crowdstrike.com',
            'aka.ms',
            'mimecastprotect.com',
            'mimecast.com',
            'microsoft.com'
          )
  )
  
  // not from CS actual
  and not (
    sender.email.domain.root_domain == 'crowdstrike.com'
    and headers.auth_summary.dmarc.pass
    and headers.auth_summary.spf.pass
    and (
      // if there is a reply-to header, make sure the root_domain is crowdstrike
      (
        length(headers.reply_to) > 0
        and all(headers.reply_to, .email.domain.root_domain == 'crowdstrike.com')
      )
      // if there isn't a reply-to, that's ok too
      or length(headers.reply_to) == 0
    )
    // return_path root_domain must be crowstrike.com
    and headers.return_path.domain.root_domain == 'crowdstrike.com'
  )
  
  // contains themed words based on Crowdstrikes Recommendations
  and (
    // safe mode
    strings.icontains(subject.subject, 'safe mode')
    or any(body.links, strings.icontains(.display_text, 'safe mode'))
    or strings.icontains(body.current_thread.text, 'safe mode')
  
    // windows recovery
    or strings.icontains(subject.subject, 'windows recovery')
    or any(body.links, strings.icontains(.display_text, 'windows recovery'))
    or strings.icontains(body.current_thread.text, 'windows recovery')
  
    // file name
    or strings.icontains(subject.subject, 'C-00000291')
    or any(body.links, strings.icontains(.display_text, 'C-00000291'))
    or strings.icontains(body.current_thread.text, 'C-00000291')
  
    // the body contains keywords and the link is sus
    or (
      any([body.current_thread.text, body.html.display_text, body.plain.raw],
          2 of (
            strings.icontains(., 'outage'),
            strings.icontains(., 'Update'),
            strings.icontains(., 'IT Issues'),
            strings.icontains(., 'Download'),
            strings.icontains(., 'Fix'),
            strings.icontains(., "password"),
            strings.icontains(., "unread messages"),
            strings.icontains(., "Shared Documents"),
            strings.icontains(., "expiration"),
            strings.icontains(., "office"),
            strings.icontains(., "expire"),
            strings.icontains(., "expiring"),
            strings.icontains(., "kindly"),
            strings.icontains(., "renew"),
            strings.icontains(., "review"),
            strings.icontains(., "emails failed"),
            strings.icontains(., "kicked out"),
            strings.icontains(., "prevented"),
            strings.icontains(., "storage quota"),
            strings.icontains(., "required now"),
            strings.icontains(., "cache"),
            strings.icontains(., "qr code"),
            strings.icontains(., "barcode"),
            strings.icontains(., "security update"),
            strings.icontains(., "quarantine")
          )
      )
      and any(body.links,
              // is sus
              .href_url.domain.domain in $url_shorteners
              or .href_url.domain.domain in $free_file_hosts
              or .href_url.domain.root_domain in $free_file_hosts
              or .href_url.domain.root_domain in $free_subdomain_hosts
              // contains a an open redirect rewriter
              or any(.href_url.rewrite.encoders,
                     strings.icontains(., "open_redirect")
              )
              // contains signs of an open redirect
              or strings.icontains(.href_url.path, 'http')
              or strings.icontains(.href_url.path, '//')
              or strings.icontains(.href_url.path, '%2f%2f')
              or strings.icontains(.href_url.query_params, 'http')
              or strings.icontains(.href_url.query_params, '//')
      )
    )
  
    // body link domains contain crowdstrike and are newly registered
    or (
      any(body.links,
          // the domain is newly registered
          (
            (
              strings.icontains(.href_url.domain.domain, 'crowdstrike')
              or (
                strings.icontains(.href_url.domain.domain, "crowd")
                and strings.icontains(.href_url.domain.domain, "falcon")
              )
            )
            // and it's a newly registered domain
            and network.whois(.href_url.domain).days_old <= 14
          )
          // the path
          or (
            (
              strings.icontains(.href_url.path, 'crowdstrike')
              or (
                strings.icontains(.href_url.path, "crowd")
                and strings.icontains(.href_url.path, "falcon")
              )
            )
            // the path has keywords, but the domain is not high-rep
            and (
              (
                .href_url.domain.domain not in $tranco_1m
                and .href_url.domain.domain not in $umbrella_1m
              )
              // if it's in Tranco or Umbrella, still include it if it's one of these
              or .href_url.domain.domain in $free_file_hosts
              or .href_url.domain.root_domain in $free_file_hosts
              or .href_url.domain.root_domain in $free_subdomain_hosts
            )
          )
      )
    )
  
    // Attachments contain links
    or (
      any(attachments,
          // Attachment file names
          strings.icontains(.file_name, 'crowdstrike')
          or (
            strings.icontains(.file_name, "crowd")
            and strings.icontains(.file_name, "falcon")
          )
          // attachment names inside of a zip
          or (
            .file_extension in~ $file_extensions_common_archives
            // explode the attachment and look at the filename
            and any(file.explode(.),
                    .depth == 1
                    and (
                      strings.icontains(.file_name, 'crowdstrike')
                      or (
                        strings.icontains(.file_name, "crowd")
                        and strings.icontains(.file_name, "falcon")
                      )
                    )
            )
          )
          // links in attachments
          or (
            any(file.explode(.),
                any(.scan.url.urls,
  
                    // the domain
                    (
                      (
                        strings.icontains(.domain.domain, 'crowdstrike')
                        or (
                          strings.icontains(.domain.domain, "crowd")
                          and strings.icontains(.domain.domain, "falcon")
                        )
                      )
                      // and it's a newly registered domain
                      and network.whois(.domain).days_old <= 14
                    )
                    // the path
                    or (
                      (
                        strings.icontains(.path, 'crowdstrike')
                        or (
                          strings.icontains(.path, "crowd")
                          and strings.icontains(.path, "falcon")
                        )
                      )
                      // the path has keywords, but the domain is not high-rep
                      and (
                        (
                          .domain.domain not in $tranco_1m
                          and .domain.domain not in $umbrella_1m
                        )
                        // if it's in Tranco or Umbrella, still include it if it's one of these
                        or .domain.domain in $free_file_hosts
                        or .domain.root_domain in $free_file_hosts
                        or .domain.root_domain in $free_subdomain_hosts
                      )
                    )
  
                    // or it's free file host/subdomain host
                    or .domain.domain in $free_file_hosts
                    or .domain.root_domain in $free_file_hosts
                    or .domain.root_domain in $free_subdomain_hosts
  
                    // LA for downloaded filenames
                    or any(ml.link_analysis(., mode="aggressive").files_downloaded,
                           (
                             strings.icontains(.file_name, 'crowdstrike')
                             or (
                               strings.icontains(.file_name, "crowd")
                               and strings.icontains(.file_name, "falcon")
                             )
                           // just an exe
                           )
                           or .file_extension in $file_extensions_executables
                           or (
                             .file_extension in~ $file_extensions_common_archives
                             // explode the attachment and look at the filename
                             and any(file.explode(.),
                                     .depth == 1
                                     and (
                                       strings.icontains(.file_name,
                                                         'crowdstrike'
                                       )
                                       or (
                                         strings.icontains(.file_name, "crowd")
                                         and strings.icontains(.file_name,
                                                               "falcon"
                                         )
                                       )
                                     )
                             )
                           )
                    )
                )
            )
          )
      )
    )
  )
  // not high trust sender domains
  and (
    (
      sender.email.domain.root_domain in $high_trust_sender_root_domains
      and not headers.auth_summary.dmarc.pass
    )
    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
  )
  
  // and no false positives and not solicited
  and (
    not profile.by_sender().any_false_positives
    and not profile.by_sender().solicited
  )
  
  // negate commonly benign conditions
  and not (
    // contains a large number of links
    length(body.links) > 20
    or (
      // contains a few links, but also contains unsub options
      length(body.links) <= 7
      and (
        any(body.links,
            strings.icontains(.display_text, "unsub")
            or any(headers.hops, any(.fields, .name == "List-Unsubscribe"))
        )
      )
    )
  )
tactics_and_techniques:
  - "Impersonation: Brand"
  - "Lookalike domain"
  - "Spoofing"
detection_methods:
  - "Sender analysis"
  - "Content analysis"