Link: Multiple HTTP protocols in single URL

Detects messages containing links with 5 or more HTTP protocol declarations within a single URL, indicating potential URL manipulation or obfuscation techniques.

Sublime rule (View on GitHub)

 1name: "Link: Multiple HTTP protocols in single URL"
 2description: "Detects messages containing links with 5 or more HTTP protocol declarations within a single URL, indicating potential URL manipulation or obfuscation techniques."
 3type: "rule"
 4severity: "medium"
 5source: |
 6  type.inbound
 7  and 0 < length(body.current_thread.links) < 10
 8  and any(body.current_thread.links,
 9          .visible
10          // no ability to loop query_params_decoded, so create the non-decoded equivlent 
11          and not strings.icontains(.href_url.url, 'unsubscribe')
12          and not strings.icontains(.display_text, 'unsubscribe')
13          and any(regex.extract(.href_url.query_params,
14                                '[?&](?P<name>[^=&]+)(?:=(?P<value>[^&]*))?'
15                  ),
16  
17                  // filter down to query params that start with a url
18                  regex.contains(.named_groups['value'],
19                                 '^(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)'
20                  )
21                  // the number of unique domains in the URL query param is greater or equal to three
22                  and length(distinct(map(filter(regex.iextract(.named_groups['value'],
23                                                                '(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)(?P<domain>[^/\s&%]+)'
24                                                 ),
25                                                 // sometimes URLs have // and produce entries we want to skip
26                                                 // so ensure it's a valid domain first
27                                                 strings.parse_domain(.named_groups['domain']
28                                                 ).error is null
29                                                 and strings.parse_domain(.named_groups['domain']
30                                                 ).valid
31                                                 // remove domain that are the same as the sender root domain
32                                                 and strings.parse_domain(.named_groups['domain']
33                                                 ).root_domain != sender.email.domain.root_domain
34                                          ),
35                                          // return just the root domian
36                                          strings.parse_domain(.named_groups['domain']
37                                          ).root_domain
38                                      ),
39                                      .
40                             )
41                  ) >= 3
42  
43                  // there are three or more total URLs in that query param
44                  and regex.count(.named_groups['value'],
45                                  '(?:https?(?:%253[Aa]|%3[Aa]|:))?(?:%252[Ff]|%2[Ff]|/)(?:%252[Ff]|%2[Ff]|/)'
46                  ) >= 3
47          )
48  )  
49tags:
50 - "Attack surface reduction"
51attack_types:
52  - "Credential Phishing"
53  - "Malware/Ransomware"
54tactics_and_techniques:
55  - "Evasion"
56detection_methods:
57  - "Content analysis"
58  - "URL analysis"
59id: "92f9d241-ebd2-53b8-9c67-6f9ec3e263b8"

Related rules

to-top