Link: Tycoon2FA phishing kit (non-exhaustive)

Detects links utilizing the Tycoon2FA phishing kit, identified by specific DOM structure patterns and CDN characteristics, combined with suspicious domain indicators such as free subdomain hosts or suspicious TLDs. As the Tycoon2FA kit is evolving, this rule will not detect all variants of Tycoon2FA phishing, and is designed to compliment existing and future detections.

Sublime rule (View on GitHub)

  1name: "Link: Tycoon2FA phishing kit (non-exhaustive)"
  2description: "Detects links utilizing the Tycoon2FA phishing kit, identified by specific DOM structure patterns and CDN characteristics, combined with suspicious domain indicators such as free subdomain hosts or suspicious TLDs. As the Tycoon2FA kit is evolving, this rule will not detect all variants of Tycoon2FA phishing, and is designed to compliment existing and future detections."
  3type: "rule"
  4severity: "high"
  5source: |
  6  type.inbound
  7  and length(body.current_thread.links) < 10
  8  and any(body.current_thread.links,
  9          // initial suspicious link check
 10          (
 11            .href_url.domain.root_domain in $free_subdomain_hosts
 12            or .href_url.domain.tld in $suspicious_tlds
 13            or any(recipients.to,
 14                   strings.icontains(..href_url.url, .email.email)
 15                   and .email.domain.valid
 16            )
 17          )
 18  
 19          // known Tycoon pattern (benign on its own, but a good confirming indicator when coupled with additional logic)
 20          and any(ml.link_analysis(.).unique_urls_accessed,
 21                  .path in ("/cdn-cgi/rum")
 22          )
 23  
 24          // begin CAPTCHA options
 25          and (
 26            // Grid "CAPTCHA"
 27            (
 28              length(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
 29                                             '//*/@class'
 30                                  ).nodes,
 31                                  .raw
 32                              ),
 33                              .
 34                     )
 35              ) == 5
 36              and all(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
 37                                              '//*/@class'
 38                                   ).nodes,
 39                                   .raw
 40                               ),
 41                               .
 42                      ),
 43                      . in ("card", "title", "hint", "grid", "dot")
 44              )
 45            )
 46            // Unsplash image selection "CAPTCHA"
 47            or (
 48              any(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
 49                                          '//*/@class'
 50                               ).nodes,
 51                               .raw
 52                           ),
 53                           .
 54                  ),
 55                  . in (
 56                    "captcha-container",
 57                    "puzzle-piece drag-hint",
 58                    "puzzle-image"
 59                  )
 60              )
 61              or length(filter(ml.link_analysis(.).unique_urls_accessed,
 62                               .domain.domain == "images.unsplash.com"
 63                        )
 64              ) > 4
 65              or any(file.explode(ml.link_analysis(.).final_dom),
 66                     length(filter(.scan.javascript.identifiers,
 67                                   strings.icontains(., "puzzle")
 68                            )
 69                     ) > 3
 70              )
 71              or strings.ilike(ml.link_analysis(.).final_dom.raw,
 72                               "*Please align the puzzle correctly*",
 73                               "*Verified! You may proceed*",
 74                               "*Human Check*"
 75              )
 76            )
 77            
 78            // Randomized image domain CAPTCHA
 79            // all image URL domains accessed are unique from each other
 80            or (
 81              length(filter(ml.link_analysis(.).unique_urls_accessed,
 82                            any([".jpg", ".png", ".jpeg"],
 83                                strings.ends_with(..path, .)
 84                            )
 85                     )
 86              ) == length(distinct(filter(ml.link_analysis(.).unique_urls_accessed,
 87                                          any([".jpg", ".png", ".jpeg"],
 88                                              strings.ends_with(..path, .)
 89                                          )
 90                                   ),
 91                                   .domain.root_domain
 92                          )
 93              )
 94              and length(filter(ml.link_analysis(.).unique_urls_accessed,
 95                                any([".jpg", ".png", ".jpeg"],
 96                                    strings.ends_with(..path, .)
 97                                )
 98                         )
 99              ) > 4
100            )
101  
102            // Reoccuring form pattern
103            or length(html.xpath(ml.link_analysis(.).final_dom,
104                                 "//form[@method='POST']//input[@name='zone' and @type='hidden']"
105                      ).nodes
106            ) == 1
107          )
108  )  
109
110attack_types:
111  - "Credential Phishing"
112tactics_and_techniques:
113  - "Free subdomain host"
114  - "Evasion"
115  - "Credential Phishing"
116detection_methods:
117  - "URL analysis"
118  - "HTML analysis"
119  - "Content analysis"
120id: "a070d4e2-9d0c-5b85-b7a5-18ee6fb66720"
to-top