AWS Discovery API Calls from VPN ASN for the First Time by Identity

Flags the first time a given IAM principal invokes a narrow set of high-signal discovery APIs (credential check, account and IAM enumeration, bucket and compute inventory, logging introspection) from a source IP whose autonomous system number (ASN) matches a curated set commonly associated with consumer VPN brands, VPN-heavy hosting, and provider networks referenced in public reporting on TeamPCP activity (for example 31173 Services AB AS39351 and Oy Crea Nova Hosting Solution Ltd). Broad List*/Describe* patterns are intentionally omitted to reduce noise. Hosting ASNs are heavily dual-use; validate source.as.number in your data and extend event.action only when your baseline allows it.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/04/03"
  3integration = ["aws"]
  4maturity = "production"
  5updated_date = "2026/07/15"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Flags the first time a given IAM principal invokes a narrow set of high-signal discovery APIs (credential check,
 11account and IAM enumeration, bucket and compute inventory, logging introspection) from a source IP whose autonomous
 12system number (ASN) matches a curated set commonly associated with consumer VPN brands, VPN-heavy hosting, and provider
 13networks referenced in public reporting on TeamPCP activity (for example 31173 Services AB AS39351 and Oy Crea Nova
 14Hosting Solution Ltd). Broad `List*`/`Describe*` patterns are intentionally omitted to reduce noise. Hosting ASNs are
 15heavily dual-use; validate `source.as.number` in your data and extend `event.action` only when your baseline allows it.
 16"""
 17false_positives = [
 18    """
 19    Administrators, developers, CI runners, and SaaS egress often exit through Datacamp, M247, Vultr, Linode, or
 20    brand-name VPN ASNs. Expect more noise on hosting ASNs than on VPN-only registrations. Exclude approved principals,
 21    accounts, CIDRs, or ASNs after review. GeoIP and ASN enrichment gaps (`source.as.number` unset) will skip events
 22    entirely. Maintain the ASN list with local intelligence (for example RIPE, BGPView, or peeringdb).
 23    """,
 24]
 25from = "now-6m"
 26index = ["filebeat-*", "logs-aws.cloudtrail-*"]
 27language = "kuery"
 28license = "Elastic License v2"
 29name = "AWS Discovery API Calls from VPN ASN for the First Time by Identity"
 30note = """## Triage and analysis
 31
 32### Investigating AWS Discovery API Calls from VPN ASN for the First Time by Identity
 33
 34This rule applies a [New Terms](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#create-new-terms-rule) condition on **`source.as.number`** and **`aws.cloudtrail.user_identity.arn`**. It fires the first time a specific principal is observed calling discovery-like APIs from an IP geolocated to one of the ASNs in the rule query (within the 10-day history window).
 35
 36**High-signal `event.action` values** (explicit allowlist in the rule query): `GetCallerIdentity`; IAM `ListUsers`,
 37`ListRoles`, `ListAccessKeys`, `GetAccountSummary`, `ListAccountAliases`, `ListGroups`, `ListMFADevices`; S3 `ListBuckets`;
 38EC2 `DescribeInstances`, `DescribeRegions`, `DescribeVpcs`, `DescribeSecurityGroups`; Lambda `ListFunctions`; RDS
 39`DescribeDBInstances`, `DescribeDBSnapshots`; DynamoDB `ListTables`; KMS `ListKeys`, `ListAliases`; CloudTrail
 40`DescribeTrails`, `LookupEvents`; Bedrock `ListFoundationModels`. Clone the rule to add actions (for example ELB or Secrets Manager) if needed.
 41
 42**Curated VPN-oriented ASNs (verify locally)** — examples this rule matches (subject to registry and enrichment updates):
 43
 44| ASN | Commonly associated operator (reference only) |
 45|-----|-----------------------------------------------|
 46| 216025 | Mullvad VPN AB |
 47| 57138 | Mullvad supporting infrastructure |
 48| 207137 | Tefincom S.A. (NordVPN-related) |
 49| 212238 | Nord / Nord Security class VPN egress in many datasets |
 50| 199218 | ProtonVPN |
 51| 209103 | Proton AG (VPN; confirm in your enrichment source) |
 52| 209854 | Surfshark Ltd. |
 53| 141039, 147049 | Packet-style VPN/colocation pools often tied to large VPN footprints |
 54| 53314 | ExpressVPN-related registration in some registries (often small; validate) |
 55| 60068 | Datacamp Limited — CDN/hosting; used by several VPN brands and many legitimate workloads (**high dual-use**) |
 56| 9009 | M247 Ltd — colocation and connectivity; common VPN/proxy exit (**high dual-use**) |
 57| 20473 | Choopa / Vultr (The Constant Company) — VPS; frequent VPN exit and automation (**high dual-use**) |
 58| 63949 | Linode LLC (Akamai cloud) — VPS; VPN exits and dev workloads (**dual-use**) |
 59| 39351 | 31173 Services AB (Sweden) — colocation/hosting; cited in TeamPCP-related reporting (**dual-use**). Not the same as **AS31173** (unrelated Ukrainian ISP). |
 60| 51765 | Oy Crea Nova Hosting Solution Ltd (Finland) — hosting; cited in TeamPCP-related reporting (**dual-use**) |
 61| 204187 | Oy Crea Nova Hosting Solution Ltd — related network under the same operator (**dual-use**) |
 62| 208172 | Proton AG — additional VPN egress network (same Proton operator as 209103 / ProtonVPN) |
 63| 9002 | RETN Limited — pan-European/global transit backbone; carries VPN/proxy egress plus heavy legitimate traffic (**high dual-use**) |
 64| 49981 | WorldStream B.V. (Netherlands) — dedicated-server/hosting; VPN exits and many legitimate workloads (**dual-use**) |
 65
 66Other ASNs sometimes seen for VPN or reseller egress (not in this rule by default) include **16276** (OVH), **14061**
 67(DigitalOcean), **24940** (Hetzner), **51167** (Contabo), and **49453** (Global Layer). Add them only if your baseline
 68shows manageable false-positive volume.
 69
 70#### Possible investigation steps
 71
 72- Confirm `aws.cloudtrail.user_identity.arn`, `aws.cloudtrail.user_identity.type`, and `aws.cloudtrail.user_identity.access_key_id`.
 73- Review `event.action` and `event.provider` in the alert; several distinct allowlisted actions from the same session suggest broader enumeration.
 74- Compare `source.ip`, `source.as.organization.name`, and `source.as.number` against your asset inventory and approved remote-access patterns.
 75- Hunt ±30 minutes for privilege changes, data access (`GetObject`, snapshot sharing), or credential operations.
 76
 77### False positive analysis
 78
 79- First-time legitimate VPN or hosting egress per identity produces a single alert per ASN until the term ages out of the window.
 80- **Datacamp (60068), M247 (9009), and Vultr (20473)** are especially noisy; consider dropping them locally if alerts exceed capacity.
 81- **31173 Services AB (39351)** and **Crea Nova (51765, 204187)** are legitimate hosting providers; only escalation-worthy when paired with unexpected identities or follow-on impact.
 82
 83### Response and remediation
 84
 85- If unexpected, rotate keys, revoke sessions, and tighten IAM; add exceptions only after documented approval.
 86
 87### Additional information
 88
 89- [CloudTrail userIdentity](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html)
 90- [BGP / ASN lookup](https://bgp.tools/) (third-party) for validating AS registrations
 91"""
 92references = [
 93    "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference.html",
 94    "https://attack.mitre.org/techniques/T1526/",
 95    "https://github.com/bountyyfi/bad-asn-list/blob/main/all.txt"
 96]
 97risk_score = 73
 98rule_id = "e3c7a891-4b2d-4e8c-a1f0-9d8e7c6b5a4d"
 99severity = "high"
100tags = [
101    "Domain: Cloud",
102    "Domain: Identity",
103    "Data Source: AWS",
104    "Data Source: Amazon Web Services",
105    "Data Source: AWS CloudTrail",
106    "Use Case: Threat Detection",
107    "Tactic: Discovery",
108    "Resources: Investigation Guide",
109]
110timestamp_override = "event.ingested"
111type = "new_terms"
112
113query = '''
114event.dataset: "aws.cloudtrail"
115    and aws.cloudtrail.user_identity.arn:(* and not *AWSServiceRoleForConfig*)
116    and not aws.cloudtrail.user_identity.type: "AWSService"
117    and event.provider: (
118        "sts.amazonaws.com" or
119        "iam.amazonaws.com" or
120        "s3.amazonaws.com" or
121        "ec2.amazonaws.com" or
122        "lambda.amazonaws.com" or
123        "rds.amazonaws.com" or
124        "dynamodb.amazonaws.com" or
125        "kms.amazonaws.com" or
126        "cloudtrail.amazonaws.com" or
127        "bedrock.amazonaws.com"
128    )
129    and event.action: (
130        "GetCallerIdentity" or
131        "ListUsers" or
132        "ListRoles" or
133        "ListAccessKeys" or
134        "GetAccountSummary" or
135        "ListAccountAliases" or
136        "ListGroups" or
137        "ListMFADevices" or
138        "ListBuckets" or
139        "DescribeInstances" or
140        "DescribeRegions" or
141        "DescribeVpcs" or
142        "DescribeSecurityGroups" or
143        "ListFunctions" or
144        "DescribeDBInstances" or
145        "DescribeDBSnapshots" or
146        "ListTables" or
147        "ListKeys" or
148        "ListAliases" or
149        "DescribeTrails" or
150        "LookupEvents" or
151        "ListFoundationModels"
152    )
153    and source.as.number: (
154        216025 or
155        57138 or
156        207137 or
157        212238 or
158        199218 or
159        209103 or
160        209854 or
161        141039 or
162        147049 or
163        53314 or
164        60068 or
165        9009 or
166        20473 or
167        63949 or
168        39351 or
169        51765 or
170        204187 or 
171        29066 or 
172        206092 or
173        208172 or
174        9002 or
175        49981
176    )
177'''
178
179[rule.investigation_fields]
180field_names = [
181    "@timestamp",
182    "user.name",
183    "user_agent.original",
184    "source.ip",
185    "source.as.number",
186    "source.as.organization.name",
187    "aws.cloudtrail.user_identity.arn",
188    "aws.cloudtrail.user_identity.type",
189    "aws.cloudtrail.user_identity.access_key_id",
190    "event.provider",
191    "event.action",
192    "event.outcome",
193    "cloud.account.id",
194    "cloud.region",
195]
196
197[[rule.threat]]
198framework = "MITRE ATT&CK"
199
200[[rule.threat.technique]]
201id = "T1526"
202name = "Cloud Service Discovery"
203reference = "https://attack.mitre.org/techniques/T1526/"
204
205[[rule.threat.technique]]
206id = "T1580"
207name = "Cloud Infrastructure Discovery"
208reference = "https://attack.mitre.org/techniques/T1580/"
209
210[rule.threat.tactic]
211id = "TA0007"
212name = "Discovery"
213reference = "https://attack.mitre.org/tactics/TA0007/"
214
215[rule.new_terms]
216field = "new_terms_fields"
217value = ["source.as.number", "user.name", "cloud.account.id"]
218[[rule.new_terms.history_window_start]]
219field = "history_window_start"
220value = "now-10d"

Triage and analysis

Investigating AWS Discovery API Calls from VPN ASN for the First Time by Identity

This rule applies a New Terms condition on source.as.number and aws.cloudtrail.user_identity.arn. It fires the first time a specific principal is observed calling discovery-like APIs from an IP geolocated to one of the ASNs in the rule query (within the 10-day history window).

High-signal event.action values (explicit allowlist in the rule query): GetCallerIdentity; IAM ListUsers, ListRoles, ListAccessKeys, GetAccountSummary, ListAccountAliases, ListGroups, ListMFADevices; S3 ListBuckets; EC2 DescribeInstances, DescribeRegions, DescribeVpcs, DescribeSecurityGroups; Lambda ListFunctions; RDS DescribeDBInstances, DescribeDBSnapshots; DynamoDB ListTables; KMS ListKeys, ListAliases; CloudTrail DescribeTrails, LookupEvents; Bedrock ListFoundationModels. Clone the rule to add actions (for example ELB or Secrets Manager) if needed.

Curated VPN-oriented ASNs (verify locally) — examples this rule matches (subject to registry and enrichment updates):

ASN Commonly associated operator (reference only)
216025 Mullvad VPN AB
57138 Mullvad supporting infrastructure
207137 Tefincom S.A. (NordVPN-related)
212238 Nord / Nord Security class VPN egress in many datasets
199218 ProtonVPN
209103 Proton AG (VPN; confirm in your enrichment source)
209854 Surfshark Ltd.
141039, 147049 Packet-style VPN/colocation pools often tied to large VPN footprints
53314 ExpressVPN-related registration in some registries (often small; validate)
60068 Datacamp Limited — CDN/hosting; used by several VPN brands and many legitimate workloads (high dual-use)
9009 M247 Ltd — colocation and connectivity; common VPN/proxy exit (high dual-use)
20473 Choopa / Vultr (The Constant Company) — VPS; frequent VPN exit and automation (high dual-use)
63949 Linode LLC (Akamai cloud) — VPS; VPN exits and dev workloads (dual-use)
39351 31173 Services AB (Sweden) — colocation/hosting; cited in TeamPCP-related reporting (dual-use). Not the same as AS31173 (unrelated Ukrainian ISP).
51765 Oy Crea Nova Hosting Solution Ltd (Finland) — hosting; cited in TeamPCP-related reporting (dual-use)
204187 Oy Crea Nova Hosting Solution Ltd — related network under the same operator (dual-use)
208172 Proton AG — additional VPN egress network (same Proton operator as 209103 / ProtonVPN)
9002 RETN Limited — pan-European/global transit backbone; carries VPN/proxy egress plus heavy legitimate traffic (high dual-use)
49981 WorldStream B.V. (Netherlands) — dedicated-server/hosting; VPN exits and many legitimate workloads (dual-use)

Other ASNs sometimes seen for VPN or reseller egress (not in this rule by default) include 16276 (OVH), 14061 (DigitalOcean), 24940 (Hetzner), 51167 (Contabo), and 49453 (Global Layer). Add them only if your baseline shows manageable false-positive volume.

Possible investigation steps

  • Confirm aws.cloudtrail.user_identity.arn, aws.cloudtrail.user_identity.type, and aws.cloudtrail.user_identity.access_key_id.
  • Review event.action and event.provider in the alert; several distinct allowlisted actions from the same session suggest broader enumeration.
  • Compare source.ip, source.as.organization.name, and source.as.number against your asset inventory and approved remote-access patterns.
  • Hunt ±30 minutes for privilege changes, data access (GetObject, snapshot sharing), or credential operations.

False positive analysis

  • First-time legitimate VPN or hosting egress per identity produces a single alert per ASN until the term ages out of the window.
  • Datacamp (60068), M247 (9009), and Vultr (20473) are especially noisy; consider dropping them locally if alerts exceed capacity.
  • 31173 Services AB (39351) and Crea Nova (51765, 204187) are legitimate hosting providers; only escalation-worthy when paired with unexpected identities or follow-on impact.

Response and remediation

  • If unexpected, rotate keys, revoke sessions, and tighten IAM; add exceptions only after documented approval.

Additional information

References

Related rules

to-top