AWS EC2 CreateKeyPair by New Principal from Non-Cloud AS Organization
Identifies the first time a given IAM principal successfully creates an EC2 key pair when the request is sourced from a
network whose autonomous system organization is not attributed to common cloud or hyperscaler providers in your GeoIP
data. Adversaries may call CreateKeyPair to stage SSH access material before launching or accessing instances. A new
terms baseline on user_identity.arn suppresses repeated noise from the same principal while still surfacing the initial
suspicious creation from an unusual egress label.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/04/08"
3integration = ["aws"]
4maturity = "production"
5updated_date = "2026/04/08"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies the first time a given IAM principal successfully creates an EC2 key pair when the request is sourced from a
11network whose autonomous system organization is not attributed to common cloud or hyperscaler providers in your GeoIP
12data. Adversaries may call CreateKeyPair to stage SSH access material before launching or accessing instances. A new
13terms baseline on `user_identity.arn` suppresses repeated noise from the same principal while still surfacing the initial
14suspicious creation from an unusual egress label.
15"""
16false_positives = [
17 """
18 Engineers creating key pairs from home ISP, corporate VPN, or colocation AS names will match until baselined.
19 GeoIP databases vary by vendor; organization labels may differ slightly from the excluded strings (for example
20 alternate Amazon or Google legal names). Tune exclusions on `source.as.organization.name` or principal ARN after
21 validation.
22 """,
23]
24from = "now-6m"
25index = ["filebeat-*", "logs-aws.cloudtrail-*"]
26language = "kuery"
27license = "Elastic License v2"
28name = "AWS EC2 CreateKeyPair by New Principal from Non-Cloud AS Organization"
29note = """## Triage and analysis
30
31### Investigating AWS EC2 CreateKeyPair by New Principal from Non-Cloud AS Organization
32
33`CreateKeyPair` creates an Amazon EC2 SSH key pair in the account; the private key material is returned to the caller
34once. This is useful for persistence or preparation for instance access.
35
36This **new terms** rule alerts the **first** time `aws.cloudtrail.user_identity.arn` matches the query within the
37configured history window. Subsequent key-pair creations by the same principal (still matching the query) are
38suppressed until the term ages out of the window.
39
40#### Possible investigation steps
41
42- Review `aws.cloudtrail.request_parameters` / `response_elements` for `keyName` and whether the key aligns with change
43 management.
44- Correlate `source.ip`, `source.geo`, and `user_agent.original` with the principal’s normal admin paths.
45- Hunt for `RunInstances`, `ImportKeyPair`, or Instance Connect activity involving the same key name or actor.
46
47### False positive analysis
48
49- First-time legitimate admin activity from a new office or VPN provider.
50- Missing `source.as.organization.name` enrichment would **not** match the query’s positive wildcard; confirm fields are
51 populated if you expect coverage.
52
53### Response and remediation
54
55- If unauthorized: delete the key pair (`DeleteKeyPair`), review IAM for `ec2:CreateKeyPair`, and rotate any credentials
56 used by the actor.
57
58### Additional information
59
60- [CreateKeyPair](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateKeyPair.html)
61"""
62references = [
63 "https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateKeyPair.html",
64]
65risk_score = 47
66rule_id = "c8e4f1a2-9b3d-4c5e-a6f7-8b9c0d1e2f3a"
67severity = "medium"
68tags = [
69 "Domain: Cloud",
70 "Domain: Identity",
71 "Data Source: AWS",
72 "Data Source: Amazon Web Services",
73 "Data Source: Amazon EC2",
74 "Use Case: Threat Detection",
75 "Tactic: Persistence",
76 "Tactic: Credential Access",
77 "Tactic: Lateral Movement",
78 "Resources: Investigation Guide",
79]
80timestamp_override = "event.ingested"
81type = "new_terms"
82
83query = '''
84event.dataset: "aws.cloudtrail"
85 and event.provider: "ec2.amazonaws.com"
86 and event.action: "CreateKeyPair"
87 and event.outcome: "success"
88 and source.as.organization.name: (
89 * and not (
90 "Amazon.com, Inc." or AMAZ* or "Google LLC" or "Microsoft Corporation"
91 )
92 )
93'''
94
95[rule.investigation_fields]
96field_names = [
97 "@timestamp",
98 "user.name",
99 "user_agent.original",
100 "source.ip",
101 "source.as.organization.name",
102 "aws.cloudtrail.user_identity.arn",
103 "aws.cloudtrail.user_identity.type",
104 "aws.cloudtrail.user_identity.access_key_id",
105 "event.action",
106 "event.outcome",
107 "cloud.account.id",
108 "cloud.region",
109 "aws.cloudtrail.request_parameters",
110 "aws.cloudtrail.response_elements",
111]
112
113[[rule.threat]]
114framework = "MITRE ATT&CK"
115
116[[rule.threat.technique]]
117id = "T1098"
118name = "Account Manipulation"
119reference = "https://attack.mitre.org/techniques/T1098/"
120
121[rule.threat.tactic]
122id = "TA0003"
123name = "Persistence"
124reference = "https://attack.mitre.org/tactics/TA0003/"
125
126[[rule.threat]]
127framework = "MITRE ATT&CK"
128
129[[rule.threat.technique]]
130id = "T1552"
131name = "Unsecured Credentials"
132reference = "https://attack.mitre.org/techniques/T1552/"
133
134[[rule.threat.technique.subtechnique]]
135id = "T1552.004"
136name = "Private Keys"
137reference = "https://attack.mitre.org/techniques/T1552/004/"
138
139[rule.threat.tactic]
140id = "TA0006"
141name = "Credential Access"
142reference = "https://attack.mitre.org/tactics/TA0006/"
143
144[[rule.threat]]
145framework = "MITRE ATT&CK"
146
147[[rule.threat.technique]]
148id = "T1021"
149name = "Remote Services"
150reference = "https://attack.mitre.org/techniques/T1021/"
151
152[[rule.threat.technique.subtechnique]]
153id = "T1021.004"
154name = "SSH"
155reference = "https://attack.mitre.org/techniques/T1021/004/"
156
157[rule.threat.tactic]
158id = "TA0008"
159name = "Lateral Movement"
160reference = "https://attack.mitre.org/tactics/TA0008/"
161
162[rule.new_terms]
163field = "new_terms_fields"
164value = ["user.name", "cloud.account.id"]
165[[rule.new_terms.history_window_start]]
166field = "history_window_start"
167value = "now-10d"
Triage and analysis
Investigating AWS EC2 CreateKeyPair by New Principal from Non-Cloud AS Organization
CreateKeyPair creates an Amazon EC2 SSH key pair in the account; the private key material is returned to the caller
once. This is useful for persistence or preparation for instance access.
This new terms rule alerts the first time aws.cloudtrail.user_identity.arn matches the query within the
configured history window. Subsequent key-pair creations by the same principal (still matching the query) are
suppressed until the term ages out of the window.
Possible investigation steps
- Review
aws.cloudtrail.request_parameters/response_elementsforkeyNameand whether the key aligns with change management. - Correlate
source.ip,source.geo, anduser_agent.originalwith the principal’s normal admin paths. - Hunt for
RunInstances,ImportKeyPair, or Instance Connect activity involving the same key name or actor.
False positive analysis
- First-time legitimate admin activity from a new office or VPN provider.
- Missing
source.as.organization.nameenrichment would not match the query’s positive wildcard; confirm fields are populated if you expect coverage.
Response and remediation
- If unauthorized: delete the key pair (
DeleteKeyPair), review IAM forec2:CreateKeyPair, and rotate any credentials used by the actor.
Additional information
References
Related rules
- AWS IAM Sensitive Operations via Lambda Execution Role
- AWS STS GetFederationToken with AdministratorAccess in Request
- AWS Lateral Movement from Kubernetes SA via AssumeRoleWithWebIdentity
- AWS EC2 Instance Console Login via Assumed Role
- AWS STS Role Chaining