Detection rules › Sublime MQL

Link: Direct POWR.io Form Builder with suspicious patterns

Severity
medium
Type
rule
Source
github.com/sublime-security/sublime-rules

Detects POWR.io forms with suspicious characteristics including unverified creators, cross-domain redirects, suspended accounts, or form owners from African time zones that don't match sender domains.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing, Callback Phishing
Tactics and techniquesSocial engineering

Event coverage

Rule body MQL

type.inbound
and (
  (
    any(filter(body.links,
               (
                 (
                   .href_url.domain.root_domain == "powr.io"
                   and strings.icontains(.href_url.path, 'form-builder')
                 )
                 or (
                   (
                     strings.icontains(.href_url.query_params, 'powr.io')
                     or strings.icontains(.href_url.query_params, 'powr%2io')
                     or strings.icontains(.href_url.query_params, 'powr%252eio')
                   )
                   and strings.icontains(.href_url.query_params, 'form-builder')
                 )
               )
        ),
        // it's credphishing
        ml.link_analysis(.).credphish.disposition == "phishing"
        // these shouldn't show up here either
        or ml.link_analysis(.).credphish.contains_login
        or ml.link_analysis(.).credphish.contains_captcha
        // there is a redirect, and that redirect goes to a different domain than the sender root domain
        or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                             'window\.CONTENT=(?P<content>[^\n]+)\;\n'
               ),
               strings.parse_json(.named_groups["content"])["afterSubmission"] == "redirect"
               and strings.parse_json(.named_groups["content"])["redirectLink"] != ""
               and not strings.icontains(strings.parse_json(.named_groups["content"]
                                         )["redirectLink"],
                                         sender.email.domain.root_domain
               )
        )
        // use the META data to inspect the "app_owner" data
        or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                             'window\.META=(?P<meta>[^\n]+)\;\n'
               ),
               // the creator has been suspended or isn't active anymore
               strings.parse_json(.named_groups["meta"])["app_owner"]["status"] == "suspended"
               or strings.parse_json(.named_groups["meta"])["app_owner"]["active"] == false
               // did not verify the email address
               or strings.parse_json(.named_groups["meta"])["app_owner"]["has_verified_email?"] == false
               // the app_owner originated from a timezone in Africa
               or strings.starts_with(strings.parse_json(.named_groups["meta"])["app_owner"]["timezone"],
                                      'Africa/'
               )
               // the creator domain doesn't match the sender root domain
               or not strings.ends_with(strings.parse_json(.named_groups["meta"]
                                        )["app_owner"]["email"],
                                        sender.email.domain.root_domain
               )
        )
    )
    or any(attachments,
           (.file_extension == "eml" or .content_type == "message/rfc822")
           and any(filter(file.parse_eml(.).body.links,
                          (
                            (
                              .href_url.domain.root_domain == "powr.io"
                              and strings.icontains(.href_url.path,
                                                    'form-builder'
                              )
                            )
                            or (
                              (
                                strings.icontains(.href_url.query_params,
                                                  'powr.io'
                                )
                                or strings.icontains(.href_url.query_params,
                                                     'powr%2io'
                                )
                                or strings.icontains(.href_url.query_params,
                                                     'powr%252eio'
                                )
                              )
                              and strings.icontains(.href_url.query_params,
                                                    'form-builder'
                              )
                            )
                          )
                   ),
                   // it's credphishing
                   ml.link_analysis(.).credphish.disposition == "phishing"
                   // these shouldn't show up here either
                   or ml.link_analysis(.).credphish.contains_login
                   or ml.link_analysis(.).credphish.contains_captcha

                   // there is a redirect, and that redirect goes to a different domain than the sender root domain
                   or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                                        'window\.CONTENT=(?P<content>[^\n]+)\;\n'
                          ),
                          strings.parse_json(.named_groups["content"])["afterSubmission"] == "redirect"
                          and strings.parse_json(.named_groups["content"])["redirectLink"] != ""
                          and not strings.icontains(strings.parse_json(.named_groups["content"]
                                                    )["redirectLink"],
                                                    sender.email.domain.root_domain
                          )
                   )
                   // the creator has been suspended
                   or any(regex.extract(ml.link_analysis(.).final_dom.raw,
                                        'window\.META=(?P<meta>[^\n]+)\;\n'
                          ),

                          // the creator has been suspended or isn't active anymore
                          strings.parse_json(.named_groups["meta"])["app_owner"]["status"] == "suspended"
                          or strings.parse_json(.named_groups["meta"])["app_owner"]["active"] == false
                          // did not verify the email address
                          or strings.parse_json(.named_groups["meta"])["app_owner"]["has_verified_email?"] == false
                          // the app_owner originated from a timezone in Africa
                          or strings.starts_with(strings.parse_json(.named_groups["meta"]
                                                 )["app_owner"]["timezone"],
                                                 'Africa/'
                          )
                          // the creator domain doesn't match the sender root domain
                          or not strings.ends_with(strings.parse_json(.named_groups["meta"]
                                                   )["app_owner"]["email"],
                                                   sender.email.domain.root_domain
                          )
                   )
           )
    )
  )
)

Detection logic

Scope: inbound message.

Detects POWR.io forms with suspicious characteristics including unverified creators, cross-domain redirects, suspended accounts, or form owners from African time zones that don't match sender domains.

  1. inbound message
  2. any of:
    • any of filter(body.links) where any holds:
      • ml.link_analysis(.).credphish.disposition is 'phishing'
      • ml.link_analysis(.).credphish.contains_login
      • ml.link_analysis(.).credphish.contains_captcha
      • any of regex.extract(...) where all hold:
        • strings.parse_json(.named_groups['content']).['afterSubmission'] is 'redirect'
        • strings.parse_json(.named_groups['content']).['redirectLink'] is not ''
        • not:
          • strings.icontains(strings.parse_json(.named_groups['content'])['redirectLink'])
      • any of regex.extract(...) where any holds:
        • strings.parse_json(.named_groups['meta']).['app_owner']['status'] is 'suspended'
        • strings.parse_json(.named_groups['meta']).['app_owner']['active'] is False
        • strings.parse_json(.named_groups['meta']).['app_owner']['has_verified_email?'] is False
        • strings.parse_json(.named_groups['meta'])['app_owner']['timezone'] starts with 'Africa/'
        • not:
          • strings.ends_with(strings.parse_json(.named_groups['meta'])['app_owner']['email'])
    • any of attachments where all hold:
      • any of:
        • .file_extension is 'eml'
        • .content_type is 'message/rfc822'
      • any of filter(...) where any holds:
        • ml.link_analysis(.).credphish.disposition is 'phishing'
        • ml.link_analysis(.).credphish.contains_login
        • ml.link_analysis(.).credphish.contains_captcha
        • any of regex.extract(...) where all hold:
          • strings.parse_json(.named_groups['content']).['afterSubmission'] is 'redirect'
          • strings.parse_json(.named_groups['content']).['redirectLink'] is not ''
          • not:
            • strings.icontains(strings.parse_json(.named_groups['content'])['redirectLink'])
        • any of regex.extract(...) where any holds:
          • strings.parse_json(.named_groups['meta']).['app_owner']['status'] is 'suspended'
          • strings.parse_json(.named_groups['meta']).['app_owner']['active'] is False
          • strings.parse_json(.named_groups['meta']).['app_owner']['has_verified_email?'] is False
          • strings.parse_json(.named_groups['meta'])['app_owner']['timezone'] starts with 'Africa/'
          • not:
            • strings.ends_with(strings.parse_json(.named_groups['meta'])['app_owner']['email'])

Inspects: attachments[].content_type, attachments[].file_extension, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.query_params, sender.email.domain.root_domain, type.inbound. Sensors: file.parse_eml, ml.link_analysis, regex.extract, strings.ends_with, strings.icontains, strings.parse_json, strings.starts_with.

Indicators matched (11)

FieldMatchValue
body.links[].href_url.domain.root_domainequalspowr.io
strings.icontainssubstringform-builder
strings.icontainssubstringpowr.io
strings.icontainssubstringpowr%2io
strings.icontainssubstringpowr%252eio
regex.extractregexwindow\.CONTENT=(?P<content>[^\n]+)\;\n
regex.extractregexwindow\.META=(?P<meta>[^\n]+)\;\n
strings.starts_withprefixAfrica/
attachments[].file_extensionequalseml
attachments[].content_typeequalsmessage/rfc822
file.parse_eml(attachments[]).body.links[].href_url.domain.root_domainequalspowr.io