Detection rules › Sublime MQL
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.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Free subdomain host, Evasion, Credential Phishing |
Event coverage
| Message attribute |
|---|
| body.current_thread |
| recipients |
| recipients.to (collection) |
| type |
Rule body MQL
type.inbound
and length(body.current_thread.links) < 10
and any(body.current_thread.links,
// initial suspicious link check
(
.href_url.domain.root_domain in $free_subdomain_hosts
or .href_url.domain.tld in $suspicious_tlds
or any(recipients.to,
strings.icontains(..href_url.url, .email.email)
and .email.domain.valid
)
)
// known Tycoon pattern (benign on its own, but a good confirming indicator when coupled with additional logic)
and any(ml.link_analysis(.).unique_urls_accessed,
.path in ("/cdn-cgi/rum")
)
// begin CAPTCHA options
and (
// Grid "CAPTCHA"
(
length(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
'//*/@class'
).nodes,
.raw
),
.
)
) == 5
and all(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
'//*/@class'
).nodes,
.raw
),
.
),
. in ("card", "title", "hint", "grid", "dot")
)
)
// Unsplash image selection "CAPTCHA"
or (
any(distinct(map(html.xpath(ml.link_analysis(.).final_dom,
'//*/@class'
).nodes,
.raw
),
.
),
. in (
"captcha-container",
"puzzle-piece drag-hint",
"puzzle-image"
)
)
or length(filter(ml.link_analysis(.).unique_urls_accessed,
.domain.domain == "images.unsplash.com"
)
) > 4
or any(file.explode(ml.link_analysis(.).final_dom),
length(filter(.scan.javascript.identifiers,
strings.icontains(., "puzzle")
)
) > 3
)
or strings.ilike(ml.link_analysis(.).final_dom.raw,
"*Please align the puzzle correctly*",
"*Verified! You may proceed*",
"*Human Check*",
"*needs to review the security of your connection before proceeding.*"
)
)
// Randomized image domain CAPTCHA
// all image URL domains accessed are unique from each other
or (
length(filter(ml.link_analysis(.).unique_urls_accessed,
any([".jpg", ".png", ".jpeg"],
strings.ends_with(..path, .)
)
)
) == length(distinct(filter(ml.link_analysis(.).unique_urls_accessed,
any([".jpg", ".png", ".jpeg"],
strings.ends_with(..path, .)
)
),
.domain.root_domain
)
)
and length(filter(ml.link_analysis(.).unique_urls_accessed,
any([".jpg", ".png", ".jpeg"],
strings.ends_with(..path, .)
)
)
) > 4
)
// Reoccuring form pattern
or length(html.xpath(ml.link_analysis(.).final_dom,
"//form[@method='POST']//input[@name='zone' and @type='hidden']"
).nodes
) == 1
)
)
Detection logic
Scope: inbound message.
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.
- inbound message
- length(body.current_thread.links) < 10
any of
body.current_thread.linkswhere all hold:any of:
- .href_url.domain.root_domain in $free_subdomain_hosts
- .href_url.domain.tld in $suspicious_tlds
any of
recipients.towhere all hold:- strings.icontains(.href_url.url)
- .email.domain.valid
any of
ml.link_analysis(.).unique_urls_accessedwhere:- .path in ('/cdn-cgi/rum')
any of:
all of:
- length(distinct(map(html.xpath(ml.link_analysis(.).final_dom, '//*/@class').nodes, .raw), .)) is 5
all of
distinct(...)where:- . in ('card', 'title', 'hint', 'grid', 'dot')
any of:
any of
distinct(...)where:- . in ('captcha-container', 'puzzle-piece drag-hint', 'puzzle-image')
- length(filter(ml.link_analysis(.).unique_urls_accessed, .domain.domain == 'images.unsplash.com')) > 4
any of
file.explode(...)where:- length(filter(.scan.javascript.identifiers, strings.icontains(., 'puzzle'))) > 3
ml.link_analysis(.).final_dom.raw matches any of 4 patterns
*Please align the puzzle correctly**Verified! You may proceed**Human Check**needs to review the security of your connection before proceeding.*
all of:
- length(filter(ml.link_analysis(.).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, .)))) is length(distinct(filter(ml.link_analysis(.).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, .))), .domain.root_domain))
- length(filter(ml.link_analysis(.).unique_urls_accessed, any(['.jpg', '.png', '.jpeg'], strings.ends_with(..path, .)))) > 4
- length(html.xpath(ml.link_analysis(.).final_dom, "//form[@method='POST']//input[@name='zone' and @type='hidden']").nodes) is 1
Inspects: body.current_thread.links, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.domain.tld, body.current_thread.links[].href_url.url, recipients.to, recipients.to[].email.domain.valid, recipients.to[].email.email, type.inbound. Sensors: file.explode, html.xpath, ml.link_analysis, strings.ends_with, strings.icontains, strings.ilike. Reference lists: $free_subdomain_hosts, $suspicious_tlds.
Indicators matched (15)
| Field | Match | Value |
|---|---|---|
ml.link_analysis(body.current_thread.links[]).unique_urls_accessed[].path | member | /cdn-cgi/rum |
distinct(...)[] | member | card |
distinct(...)[] | member | title |
distinct(...)[] | member | hint |
distinct(...)[] | member | grid |
distinct(...)[] | member | dot |
distinct(...)[] | member | captcha-container |
distinct(...)[] | member | puzzle-piece drag-hint |
distinct(...)[] | member | puzzle-image |
ml.link_analysis(body.current_thread.links[]).unique_urls_accessed[].domain.domain | equals | images.unsplash.com |
strings.icontains | substring | puzzle |
strings.ilike | substring | *Please align the puzzle correctly* |
3 more
strings.ilike | substring | *Verified! You may proceed* |
strings.ilike | substring | *Human Check* |
strings.ilike | substring | *needs to review the security of your connection before proceeding.* |