Link: Google Cloud Storage with suffixed unsubscribe bucket

Detects messages with exactly two Google Cloud Storage links serving the same file from two buckets, where one bucket name is the other plus a suffix (e.g. 'unsb'). Observed in bulk health-supplement, reward survey and fake storage-alert campaigns.

Sublime rule (View on GitHub)

 1name: "Link: Google Cloud Storage with suffixed unsubscribe bucket"
 2description: "Detects messages with exactly two Google Cloud Storage links serving the same file from two buckets, where one bucket name is the other plus a suffix (e.g. 'unsb'). Observed in bulk health-supplement, reward survey and fake storage-alert campaigns."
 3type: "rule"
 4severity: "medium"
 5source: |
 6    type.inbound
 7    // two distinct paths
 8    and length(distinct(map(filter(body.links,
 9                                   .href_url.domain.domain == "storage.googleapis.com"
10                            ),
11                            .href_url.path
12                        )
13               )
14    ) == 2
15    // split each distinct path into bucket and trailer once
16    and any(map(distinct(filter(body.links,
17                                .href_url.domain.domain == "storage.googleapis.com"
18                         ),
19                         .href_url.path
20                ),
21                // return just the bucket/trailer for the path
22                regex.extract(.href_url.path,
23                              '^/(?P<bucket>[^/]+)/(?P<trailer>.+)$'
24                )[0]
25            ),
26            // loop the links that aren't the current .href_url.path (from the outer loop)
27            any(map(distinct(filter(body.links,
28                                    .href_url.domain.domain == "storage.googleapis.com"
29                                    and .href_url.path != ..full_match
30                             ),
31                             // return just the .href_url.path
32                             .href_url.path
33                    ),
34                    // create the bucket/trailer for the path
35                    regex.extract(.href_url.path,
36                                  '^/(?P<bucket>[^/]+)/(?P<trailer>.+)$'
37                    )[0]
38                ),
39                // this bucket is the outer bucket plus a suffix, serving the same trailer
40                strings.starts_with(.named_groups['bucket'],
41                                    ..named_groups['bucket']
42                )
43                and .named_groups['trailer'] == ..named_groups['trailer']
44            )
45    )    
46attack_types:
47  - "Spam"
48  - "Credential Phishing"
49tactics_and_techniques:
50  - "Free file host"
51  - "Evasion"
52  - "Social engineering"
53detection_methods:
54  - "URL analysis"
55id: "7e303d15-f91d-59ef-b4b7-12a799b05f34"
to-top