Skip to content

Commit 49bf2cf

Browse files
Update latest docs (#7020)
1 parent 45fb497 commit 49bf2cf

File tree

148 files changed

+14554
-1513
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+14554
-1513
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
[[prebuilt-rule-8-19-4-aws-access-token-used-from-multiple-addresses]]
2+
=== AWS Access Token Used from Multiple Addresses
3+
4+
This rule identifies potentially suspicious activity by detecting instances where a single IAM user's temporary session token is accessed from multiple IP addresses within a short time frame. Such behavior may suggest that an adversary has compromised temporary credentials and is utilizing them from various locations. To enhance detection accuracy and minimize false positives, the rule incorporates criteria that evaluate unique IP addresses, user agents, cities, and networks. These additional checks help distinguish between legitimate distributed access patterns and potential credential misuse. Detected activities are classified into different types based on the combination of unique indicators, with each classification assigned a fidelity score reflecting the likelihood of malicious behavior. High fidelity scores are given to patterns most indicative of threats, such as multiple unique IPs, networks, cities, and user agents. Medium and low fidelity scores correspond to less severe patterns, enabling security teams to effectively prioritize alerts.
5+
6+
*Rule type*: esql
7+
8+
*Rule indices*: None
9+
10+
*Severity*: medium
11+
12+
*Risk score*: 47
13+
14+
*Runs every*: 5m
15+
16+
*Searches indices from*: now-32m ({ref}/common-options.html#date-math[Date Math format], see also <<rule-schedule, `Additional look-back time`>>)
17+
18+
*Maximum alerts per execution*: 100
19+
20+
*References*:
21+
22+
* https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/
23+
24+
*Tags*:
25+
26+
* Domain: Cloud
27+
* Data Source: AWS
28+
* Data Source: Amazon Web Services
29+
* Data Source: AWS IAM
30+
* Data Source: AWS CloudTrail
31+
* Tactic: Initial Access
32+
* Use Case: Identity and Access Audit
33+
* Resources: Investigation Guide
34+
35+
*Version*: 102
36+
37+
*Rule authors*:
38+
39+
* Elastic
40+
41+
*Rule license*: Elastic License v2
42+
43+
44+
==== Investigation guide
45+
46+
47+
48+
*Triage and Analysis*
49+
50+
51+
52+
*Investigating AWS Access Token Used from Multiple Addresses*
53+
54+
55+
Access tokens are bound to a single user. Usage from multiple IP addresses may indicate the token was stolen and used elsewhere. By correlating this with additional detection criteria like multiple user agents, different cities, and different networks, we can improve the fidelity of the rule and help to eliminate false positives associated with expected behavior, like dual-stack IPV4/IPV6 usage.
56+
57+
58+
*Possible Investigation Steps*
59+
60+
61+
- **Identify the IAM User**: Examine the `aws.cloudtrail.user_identity.arn` stored in `user_id` and correlate with the `source.ips` stored in `ip_list` and `unique_ips` count to determine how widely the token was used.
62+
- **Correlate Additional Detection Context**: Examine `activity_type` and `fidelity_score` to determine additional cities, networks or user agents associated with the token usage.
63+
- **Determine Access Key Type**: Examine the `access_key_id` to determine whether the token is short-term (beginning with ASIA) or long-term (beginning with AKIA).
64+
- **Check Recent MFA Events**: Determine whether the user recently enabled MFA, registered devices, or assumed a role using this token.
65+
- **Review Workload Context**: Confirm whether the user was expected to be active across multiple cities, networks or user agent environments.
66+
- **Trace Adversary Movement**: Pivot to related actions (e.g., `s3:ListBuckets`, `iam:ListUsers`, `sts:GetCallerIdentity`) to track further enumeration.
67+
68+
69+
*False Positive Analysis*
70+
71+
72+
- Automation frameworks that rotate through multiple IPs or cloud functions with dynamic egress IPs may cause this alert to fire.
73+
- Confirm geolocation and workload context before escalating.
74+
75+
76+
*Response and Remediation*
77+
78+
79+
- **Revoke the Token**: Disable or rotate the IAM credentials and invalidate the temporary session token.
80+
- **Audit the Environment**: Look for signs of lateral movement or data access during the token's validity.
81+
- **Strengthen Controls**: Require MFA for high-privilege actions, restrict access via policy conditions (e.g., IP range or device).
82+
83+
84+
*References*
85+
86+
87+
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html[IAM Long-Term Credentials]
88+
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html[STS Temporary Credentials]
89+
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html[Using MFA with Temporary Credentials]
90+
- https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-standards-fsbp-controls.html[AWS Threat Detection Use Cases]
91+
92+
93+
==== Rule query
94+
95+
96+
[source, js]
97+
----------------------------------
98+
from logs-aws.cloudtrail* metadata _id, _version, _index
99+
| where @timestamp > now() - 30 minutes
100+
and event.dataset == "aws.cloudtrail"
101+
and aws.cloudtrail.user_identity.arn is not null
102+
and aws.cloudtrail.user_identity.type == "IAMUser"
103+
and source.ip is not null
104+
and not (
105+
user_agent.original like "%Terraform%" or
106+
user_agent.original like "%Ansible%" or
107+
user_agent.original like "%Pulumni%"
108+
)
109+
and `source.as.organization.name` != "AMAZON-AES"
110+
and event.provider not in (
111+
"health.amazonaws.com", "monitoring.amazonaws.com", "notifications.amazonaws.com",
112+
"ce.amazonaws.com", "cost-optimization-hub.amazonaws.com",
113+
"servicecatalog-appregistry.amazonaws.com", "securityhub.amazonaws.com"
114+
)
115+
116+
| eval
117+
Esql.time_window_date_trunc = date_trunc(30 minutes, @timestamp),
118+
Esql.aws_cloudtrail_user_identity_arn = aws.cloudtrail.user_identity.arn,
119+
Esql.aws_cloudtrail_user_identity_access_key_id = aws.cloudtrail.user_identity.access_key_id,
120+
Esql.source_ip = source.ip,
121+
Esql.user_agent_original = user_agent.original,
122+
Esql.source_ip_string = to_string(source.ip),
123+
Esql.source_ip_user_agent_pair = concat(Esql.source_ip_string, " - ", user_agent.original),
124+
Esql.source_ip_city_pair = concat(Esql.source_ip_string, " - ", source.geo.city_name),
125+
Esql.source_geo_city_name = source.geo.city_name,
126+
Esql.event_timestamp = @timestamp,
127+
Esql.source_network_org_name = `source.as.organization.name`
128+
129+
| stats
130+
Esql.event_action_values = values(event.action),
131+
Esql.event_provider_values = values(event.provider),
132+
Esql.aws_cloudtrail_user_identity_access_key_id_values = values(Esql.aws_cloudtrail_user_identity_access_key_id),
133+
Esql.aws_cloudtrail_user_identity_arn_values = values(Esql.aws_cloudtrail_user_identity_arn),
134+
Esql.source_ip_values = values(Esql.source_ip),
135+
Esql.user_agent_original_values = values(Esql.user_agent_original),
136+
Esql.source_ip_user_agent_pair_values = values(Esql.source_ip_user_agent_pair),
137+
Esql.source_geo_city_name_values = values(Esql.source_geo_city_name),
138+
Esql.source_ip_city_pair_values = values(Esql.source_ip_city_pair),
139+
Esql.source_network_org_name_values = values(Esql.source_network_org_name),
140+
Esql.source_ip_count_distinct = count_distinct(Esql.source_ip),
141+
Esql.user_agent_original_count_distinct = count_distinct(Esql.user_agent_original),
142+
Esql.source_geo_city_name_count_distinct = count_distinct(Esql.source_geo_city_name),
143+
Esql.source_network_org_name_count_distinct = count_distinct(Esql.source_network_org_name),
144+
Esql.timestamp_first_seen = min(Esql.event_timestamp),
145+
Esql.timestamp_last_seen = max(Esql.event_timestamp),
146+
Esql.event_count = count()
147+
by Esql.time_window_date_trunc, Esql.aws_cloudtrail_user_identity_access_key_id
148+
149+
| eval
150+
Esql.activity_type = case(
151+
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_network_city_user_agent",
152+
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_network_city",
153+
Esql.source_ip_count_distinct >= 2 and Esql.source_geo_city_name_count_distinct >= 2, "multiple_ip_and_city",
154+
Esql.source_ip_count_distinct >= 2 and Esql.source_network_org_name_count_distinct >= 2, "multiple_ip_and_network",
155+
Esql.source_ip_count_distinct >= 2 and Esql.user_agent_original_count_distinct >= 2, "multiple_ip_and_user_agent",
156+
"normal_activity"
157+
),
158+
Esql.activity_fidelity_score = case(
159+
Esql.activity_type == "multiple_ip_network_city_user_agent", "high",
160+
Esql.activity_type == "multiple_ip_network_city", "high",
161+
Esql.activity_type == "multiple_ip_and_city", "medium",
162+
Esql.activity_type == "multiple_ip_and_network", "medium",
163+
Esql.activity_type == "multiple_ip_and_user_agent", "low"
164+
)
165+
166+
| keep
167+
Esql.time_window_date_trunc,
168+
Esql.activity_type,
169+
Esql.activity_fidelity_score,
170+
Esql.event_count,
171+
Esql.timestamp_first_seen,
172+
Esql.timestamp_last_seen,
173+
Esql.aws_cloudtrail_user_identity_arn_values,
174+
Esql.aws_cloudtrail_user_identity_access_key_id_values,
175+
Esql.event_action_values,
176+
Esql.event_provider_values,
177+
Esql.source_ip_values,
178+
Esql.user_agent_original_values,
179+
Esql.source_ip_user_agent_pair_values,
180+
Esql.source_geo_city_name_values,
181+
Esql.source_ip_city_pair_values,
182+
Esql.source_network_org_name_values,
183+
Esql.source_ip_count_distinct,
184+
Esql.user_agent_original_count_distinct,
185+
Esql.source_geo_city_name_count_distinct,
186+
Esql.source_network_org_name_count_distinct
187+
188+
| where Esql.activity_type != "normal_activity"
189+
190+
----------------------------------
191+
192+
*Framework*: MITRE ATT&CK^TM^
193+
194+
* Tactic:
195+
** Name: Initial Access
196+
** ID: TA0001
197+
** Reference URL: https://attack.mitre.org/tactics/TA0001/
198+
* Technique:
199+
** Name: Valid Accounts
200+
** ID: T1078
201+
** Reference URL: https://attack.mitre.org/techniques/T1078/
202+
* Sub-technique:
203+
** Name: Cloud Accounts
204+
** ID: T1078.004
205+
** Reference URL: https://attack.mitre.org/techniques/T1078/004/
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
[[prebuilt-rule-8-19-4-aws-bedrock-detected-multiple-attempts-to-use-denied-models-by-a-single-user]]
2+
=== AWS Bedrock Detected Multiple Attempts to use Denied Models by a Single User
3+
4+
Identifies multiple successive failed attempts to use denied model resources within AWS Bedrock. This could indicated attempts to bypass limitations of other approved models, or to force an impact on the environment by incurring exhorbitant costs.
5+
6+
*Rule type*: esql
7+
8+
*Rule indices*: None
9+
10+
*Severity*: high
11+
12+
*Risk score*: 73
13+
14+
*Runs every*: 10m
15+
16+
*Searches indices from*: now-60m ({ref}/common-options.html#date-math[Date Math format], see also <<rule-schedule, `Additional look-back time`>>)
17+
18+
*Maximum alerts per execution*: 100
19+
20+
*References*:
21+
22+
* https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-components.html
23+
* https://atlas.mitre.org/techniques/AML.T0015
24+
* https://atlas.mitre.org/techniques/AML.T0034
25+
* https://www.elastic.co/security-labs/elastic-advances-llm-security
26+
27+
*Tags*:
28+
29+
* Domain: LLM
30+
* Data Source: AWS Bedrock
31+
* Data Source: AWS S3
32+
* Resources: Investigation Guide
33+
* Use Case: Policy Violation
34+
* Mitre Atlas: T0015
35+
* Mitre Atlas: T0034
36+
37+
*Version*: 5
38+
39+
*Rule authors*:
40+
41+
* Elastic
42+
43+
*Rule license*: Elastic License v2
44+
45+
46+
==== Investigation guide
47+
48+
49+
50+
*Triage and analysis*
51+
52+
53+
54+
*Investigating AWS Bedrock Detected Multiple Attempts to use Denied Models by a Single User*
55+
56+
57+
Amazon Bedrock is AWS’s managed service that enables developers to build and scale generative AI applications using large foundation models (FMs) from top providers.
58+
59+
Bedrock offers a variety of pretrained models from Amazon (such as the Titan series), as well as models from providers like Anthropic, Meta, Cohere, and AI21 Labs.
60+
61+
62+
*Possible investigation steps*
63+
64+
65+
- Identify the user account that attempted to use denied models.
66+
- Investigate other alerts associated with the user account during the past 48 hours.
67+
- Consider the time of day. If the user is a human (not a program or script), did the activity take place during a normal time of day?
68+
- Examine the account's attempts to access Amazon Bedrock models in the last 24 hours.
69+
- If you suspect the account has been compromised, scope potentially compromised assets by tracking Amazon Bedrock model access, prompts generated, and responses to the prompts by the account in the last 24 hours.
70+
71+
72+
*False positive analysis*
73+
74+
75+
- Verify the user account that attempted to use denied models, is a legitimate misunderstanding by users or overly strict policies.
76+
77+
78+
*Response and remediation*
79+
80+
81+
- Initiate the incident response process based on the outcome of the triage.
82+
- Disable or limit the account during the investigation and response.
83+
- Identify the possible impact of the incident and prioritize accordingly; the following actions can help you gain context:
84+
- Identify the account role in the cloud environment.
85+
- Identify if the attacker is moving laterally and compromising other Amazon Bedrock Services.
86+
- Identify any regulatory or legal ramifications related to this activity.
87+
- Review the permissions assigned to the implicated user group or role behind these requests to ensure they are authorized and expected to access bedrock and ensure that the least privilege principle is being followed.
88+
- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.
89+
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
90+
91+
92+
==== Setup
93+
94+
95+
96+
*Setup*
97+
98+
99+
This rule requires that guardrails are configured in AWS Bedrock. For more information, see the AWS Bedrock documentation:
100+
101+
https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-create.html
102+
103+
104+
==== Rule query
105+
106+
107+
[source, js]
108+
----------------------------------
109+
from logs-aws_bedrock.invocation-*
110+
111+
// Filter for access denied errors from GenAI responses
112+
| where gen_ai.response.error_code == "AccessDeniedException"
113+
114+
// keep ECS and response fields
115+
| keep
116+
user.id,
117+
gen_ai.request.model.id,
118+
cloud.account.id,
119+
gen_ai.response.error_code
120+
121+
// count total denials per user/model/account
122+
| stats
123+
Esql.ml_response_access_denied_count = count(*)
124+
by
125+
user.id,
126+
gen_ai.request.model.id,
127+
cloud.account.id
128+
129+
// Filter for users with repeated denials
130+
| where Esql.ml_response_access_denied_count > 3
131+
132+
// sort by volume of denials
133+
| sort Esql.ml_response_access_denied_count desc
134+
135+
----------------------------------

0 commit comments

Comments
 (0)