[New Hunt] Add AWS Hunting Queries to Shared Hunting Library (#3988)
* new hunt queries for aws * sendcommand and getuserpassword queries * s3 bucket access and secrets manager requests added * ssm start session and service logging deleted added * adding federated authentication queries * added ec2 modify instance attribute query * adding backdoor role creation query * 2 new queries for discovery; added lookback windows * added new hunting query for IAM activity with no MFA session * added missing time windows * adding new query for lambda add permissions * adjusted query format * added new query for ec2 instance deployment anomalies * updated queries based on feedback; regenerated docs * fixed queries * removed new rule
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# High Frequency of EC2 Multi-Region `DescribeInstances` API Calls
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a user makes multiple `DescribeInstances` API calls in multiple regions within a 30-second window. The `DescribeInstances` API call retrieves information about one or more EC2 instances in a region. High frequency of `DescribeInstances` API calls across multiple regions may indicate an adversary attempting to discover the EC2 instances in the account or perform reconnaissance on the EC2 environment.
|
||||
|
||||
- **UUID:** `e6e78858-6482-11ef-93bd-f661ea17fbcc`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [High Frequency of EC2 Multi-Region `DescribeInstances` API Calls](../queries/ec2_discovery_multi_region_describe_instance_calls.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
|
||||
// filter for DescribeInstances API calls
|
||||
| where event.dataset == "aws.cloudtrail" and event.provider == "ec2.amazonaws.com" and event.action == "DescribeInstances"
|
||||
|
||||
// truncate the timestamp to a 30-second window
|
||||
| eval target_time_window = DATE_TRUNC(30 seconds, @timestamp)
|
||||
|
||||
// count the number of unique regions and total API calls within the 30-second window
|
||||
| stats region_count = count_distinct(cloud.region), window_count = count(*) by target_time_window, aws.cloudtrail.user_identity.arn
|
||||
|
||||
// filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window
|
||||
| where region_count >= 10 and window_count >= 10
|
||||
|
||||
// sort the results by time windows in descending order
|
||||
| sort target_time_window desc
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `aws.cloudtrail.user_identity.arn` field to identify the user making the requests and their role permissions
|
||||
- Use the `cloud.region` field to identify the regions where the `DescribeInstances` API calls were made
|
||||
- If leveraging SSM, query for `StartSession` API calls to determine if the user is attempting to establish a session with the EC2 instances
|
||||
- Filter for `event.provider` is `ec2.amazonaws.com` to pivot on unusual activity related to EC2 instances
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1580](https://attack.mitre.org/techniques/T1580)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,58 @@
|
||||
# High Frequency of EC2 Multi-Region `GetServiceQuota` API Calls
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a single AWS resource is making `GetServiceQuota` API calls for the EC2 service quota L-1216C47A in more than 10 regions within a 30-second window. Quota code L-1216C47A represents on-demand instances which are used by adversaries to deploy malware and mine cryptocurrency. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance.
|
||||
|
||||
- **UUID:** `7a083b24-6482-11ef-8a8f-f661ea17fbcc`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [High Frequency of EC2 Multi-Region `GetServiceQuota` API Calls](../queries/ec2_discovery_multi_region_get_service_quota_calls.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
|
||||
// filter for GetServiceQuota API calls
|
||||
| where event.dataset == "aws.cloudtrail" and event.action == "GetServiceQuota"
|
||||
|
||||
// truncate the timestamp to a 30-second window
|
||||
| eval target_time_window = DATE_TRUNC(30 seconds, @timestamp)
|
||||
|
||||
// pre-process the request parameters to extract the service code and quota code
|
||||
| dissect aws.cloudtrail.request_parameters "{%{?service_code_key}=%{service_code}, %{?quota_code_key}=%{quota_code}}"
|
||||
|
||||
// filter for EC2 service quota L-1216C47A (vCPU on-demand instances)
|
||||
| where service_code == "ec2" and quota_code == "L-1216C47A"
|
||||
|
||||
// count the number of unique regions and total API calls within the 30-second window
|
||||
| stats region_count = count_distinct(cloud.region), window_count = count(*) by target_time_window, aws.cloudtrail.user_identity.arn
|
||||
|
||||
// filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window
|
||||
| where region_count >= 10 and window_count >= 10
|
||||
|
||||
// sort the results by time windows in descending order
|
||||
| sort target_time_window desc
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `aws.cloudtrail.user_identity.arn` field to identify the user making the requests and their role permissions
|
||||
- Use the `cloud.region` field to identify the regions where the `GetServiceQuota` API calls were made
|
||||
- Review Elastic Defend alerts for endpoint related activity to identify potential malware or cryptocurrency mining activity
|
||||
- If a valid account compromise is suspected, review source.* fields for the IP address and geographical location of the request and compare with the user's typical behavior
|
||||
- Query for `RunInstances` API calls to determine if new instances were launched using the on-demand instances
|
||||
- If new instances were launched, review the instance metadata and user data scripts for malicious content
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1580](https://attack.mitre.org/techniques/T1580)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,49 @@
|
||||
# High EC2 Instance Deployment Count Attempts by Single User or Role
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a user makes EC2 `RunInstances` API calls with a high instance deployment count within a 7-day window. The `RunInstances` API call launches one or more instances in a specified subnet. High instance deployment counts may indicate an adversary attempting to deploy a large number of instances for cryptomining or other malicious activities. This may also aid in identifying potential resource abuse or misconfigurations.
|
||||
|
||||
- **UUID:** `c3d24ae8-655d-11ef-a990-f661ea17fbcc`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [High EC2 Instance Deployment Count Attempts by Single User or Role](../queries/ec2_high_instance_deployment_count_attempts.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "ec2.amazonaws.com"
|
||||
and event.action == "RunInstances"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*minCount.*maxCount.*"
|
||||
| eval date = DATE_FORMAT("YYYY-mm-dd", @timestamp)
|
||||
| dissect aws.cloudtrail.request_parameters "%{}subnetId=%{subnet_id},"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}minCount=%{min_count},"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}maxCount=%{max_count}}]},"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}instanceType=%{instance_type},"
|
||||
| stats
|
||||
target_instance_count = sum(to_integer(max_count) - to_integer(min_count) + 1),
|
||||
user_attempts = count(*) by user.name, date, subnet_id, instance_type, event.outcome
|
||||
| where target_instance_count >= 10
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `aws.cloudtrail.user_identity.arn` field to identify the user making the requests and their role permissions
|
||||
- Review `cloud.region` to identify the regions where the `RunInstances` API calls were made
|
||||
- `subnet_id` should be reviewed to identify the subnet where the instances are being deployed but can also help pivot and narrow down the scope of further queries
|
||||
- `instance_type` should be reviewed to identify the type of instances being deployed. Cryptomining campaigns often deploy specific instance types to maximize mining efficiency
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1578.002](https://attack.mitre.org/techniques/T1578/002)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,42 @@
|
||||
# EC2 Modify Instance Attribute User Data
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a user modifies the user data attribute of an EC2 instance. The user data attribute is a script that runs when the instance is launched. Modifying the user data attribute could indicate an adversary attempting to gain persistence or execute malicious code on the instance.
|
||||
|
||||
- **UUID:** `f11ac62c-5f42-11ef-9d72-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [EC2 Modify Instance Attribute User Data](../queries/ec2_modify_instance_attribute_user_data.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "ec2.amazonaws.com"
|
||||
and event.action == "ModifyInstanceAttribute"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*attribute=userData.*"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{instance_id_key}=%{instance_id}, %{attribute_key}=%{attribute}, %{value_key}=%{value}}"
|
||||
| stats user_attribute_modify_count = count(*) by aws.cloudtrail.user_identity.arn, event.outcome
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `instance_id` field to identify the EC2 instance for which the user data attribute was modified
|
||||
- Pivot into the EC2 instance if possible and examine the user data script ('/var/lib/cloud/instance/scripts/userdata.txt') for malicious content
|
||||
- To modify an EC2 instance's user data attribute, the instance must be stopped, therefore check for `StopInstances` API calls in `event.action` field to determine if the instance was stopped and started
|
||||
- AWS redacts the value of the `user_data` attribute in the CloudTrail logs, so the actual script content will not be visible in the logs
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1059.009](https://attack.mitre.org/techniques/T1059/009)
|
||||
- [T1037](https://attack.mitre.org/techniques/T1037)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,40 @@
|
||||
# EC2 Suspicious Get User Password Request
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a user makes multiple `GetPasswordData` requests for an EC2 instance. The `GetPasswordData` API call retrieves the encrypted administrator password for an instance running Windows. This API call typically only occurs during the initial launch of an instance or when the password is reset. Multiple requests for the same instance may indicate an adversary attempting to escalate privileges or move laterally within the EC2 environment.
|
||||
|
||||
- **UUID:** `408ba5f6-5db7-11ef-a01c-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [EC2 Suspicious Get User Password Request](../queries/ec2_suspicious_get_user_password_request.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "ec2.amazonaws.com" and event.action == "GetPasswordData"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{?instance_key}=%{instance_id}}"
|
||||
| stats instance_count = count_distinct(instance_id) by aws.cloudtrail.user_identity.arn
|
||||
| where instance_count >= 2
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `instance_id` field to identify the EC2 instance for which the `GetPasswordData` requests were made
|
||||
- Check for `RunInstances` API calls to determine if the instance was recently launched or if the password was reset
|
||||
- `aws.cloudtrail.error_code` can provide additional context if the `GetPasswordData` request failed or was denied
|
||||
- Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions
|
||||
- If a valid account compromise is suspected, review source.* fields for the IP address and geographical location of the request and compare with the user's typical behavior
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1552.005](https://attack.mitre.org/techniques/T1552/005)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,43 @@
|
||||
# IAM Assume Role Creation with Attached Policy
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query gathers data for evidence of an adversary creating an IAM role with an inline attached policy that allows the role to assume another role. This only identifies flags for AWS account IDs that are different from the account ID where the role is being created indicating a potential backdoor IAM role.
|
||||
|
||||
- **UUID:** `429824b6-60b2-11ef-b0a4-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [IAM Assume Role Creation with Attached Policy](../queries/iam_assume_role_creation_with_attached_policy.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "iam.amazonaws.com"
|
||||
and event.action == "CreateRole"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*Allow.*"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*sts:AssumeRole.*"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*assumeRolePolicyDocument.*"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*arn:aws:iam.*"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}AWS\": \"arn:aws:iam::%{target_account_id}:"
|
||||
| where cloud.account.id != target_account_id
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Review the `target_account_id` field to identify the account that the role is being created in. This could be another AWS account your organization owns.
|
||||
- Review `aws.cloudtrail.request_parameters` to identify the role being created and the policy being attached. If the inline policy includes overly permissive permissions such as `AdministratorAccess`, this could be a sign of malicious activity.
|
||||
- Pivot for `event.action` where the value is `AttachRolePolicy` to identify the policy being attached to the role.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1098.003](https://attack.mitre.org/techniques/T1098/003)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,39 @@
|
||||
# IAM User Activity with No MFA Session
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query gathers data for evidence of an IAM user activity with no MFA session. This query identifies IAM user activity where the user is not MFA authenticated. Adversaries often target IAM users with weak or no MFA protection to gain unauthorized access to AWS resources after compromising the user's credentials via phishing, third-party breaches, or brute-forcing.
|
||||
|
||||
- **UUID:** `913a47be-649c-11ef-a693-f661ea17fbcc`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [IAM User Activity with No MFA Session](../queries/iam_user_activity_with_no_mfa_session.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.dataset == "aws.cloudtrail"
|
||||
and aws.cloudtrail.user_identity.type == "IAMUser"
|
||||
and aws.cloudtrail.user_identity.session_context.mfa_authenticated == "false"
|
||||
and not user_agent.original in ("cloudformation.amazonaws.com", "application-autoscaling.amazonaws.com", "AWS Internal")
|
||||
and (aws.cloudtrail.user_identity.access_key_id is null or aws.cloudtrail.user_identity.access_key_id == "")
|
||||
| stats activity_counts = count(*) by event.provider, event.action, aws.cloudtrail.user_identity.arn
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Review the `user_identity.arn` field to identify if activity is sourcing from a browser or programmatically via the AWS CLI or SDK.
|
||||
- Review aggregated counts of API calls made for suspicious discovery or reconnaissance such as `List*`, `Describe*`, or `Get*` API calls.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1078.004](https://attack.mitre.org/techniques/T1078/004)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,44 @@
|
||||
# User Creation with Administrator Policy Assigned
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query gathers data for evidence of an adversary creating a user in AWS and then assigning administrative rights to that user. The `CreateUser` API call to IAM allows the adversary to create the user and then `AttachUserPolicy` where `policy/AdministratorAccess` is identified should match attempts to assign administrative privileges.
|
||||
|
||||
- **UUID:** `696c3f40-5b54-11ef-b9df-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [User Creation with Administrator Policy Assigned](../queries/iam_user_creation_with_administrator_policy_assigned.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "iam.amazonaws.com"
|
||||
and event.outcome == "success"
|
||||
and (event.action == "CreateUser" or
|
||||
(event.action == "AttachUserPolicy" and aws.cloudtrail.request_parameters rlike ".*AdministratorAccess.*"))
|
||||
| stats unique_action_count = count_distinct(event.action) by user.target.name
|
||||
| where unique_action_count == 2
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `aws.cloudtrail.request_parameters` contains the target user the policy is being attached to or the user being created
|
||||
- `count_distinct` ensures that the user was just created, but also had the administrative policy attached within the respective time window
|
||||
- There is a chance that timestamps could be out-of-order based on ingestion and event generation in AWS CloudTrail
|
||||
- The target user's IAM policies should be reviewed to ensure MFA is enabled
|
||||
- Reviewing the AWS ARN in the event should identify which user made these changes; this user ID should be used to pivot into potential valid account compromise
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1098.003](https://attack.mitre.org/techniques/T1098/003)
|
||||
- [T1136.003](https://attack.mitre.org/techniques/T1136/003)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,42 @@
|
||||
# Lambda Add Permissions for Write Actions to Function
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query gathers data for evidence of an adversary adding permissions to a Lambda function that allows write actions. The `AddPermission` API call to Lambda allows the adversary to add permissions to a Lambda function. This query identifies when the `AddPermission` API call is used to add permissions that allow write actions to a Lambda function. Adversaries may use this technique to grant themselves additional permissions to write to a Lambda function, which could be used to execute malicious code or exfiltrate data.
|
||||
|
||||
- **UUID:** `e3206d1c-64a9-11ef-a642-f661ea17fbcc`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [Lambda Add Permissions for Write Actions to Function](../queries/lambda_add_permissions_for_write_actions_to_function.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "lambda.amazonaws.com"
|
||||
and event.action RLIKE "AddPermission.*"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{?principal_key}=%{principal_id}, %{?function_name_key}=%{function_name}, %{?statement_key}=%{statement_value}, %{?action_key}=lambda:%{action_value}}"
|
||||
| eval write_action = (starts_with(action_value, "Invoke") or starts_with("Update", action_value) or starts_with("Put", action_value))
|
||||
| where write_action == true
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Analyze the `principal_id` to identify the entity that the permission is being granted to. Adversaries may use this technique to grant themselves additional permissions.
|
||||
- Review the `function_name` to identify the Lambda function that the permission is being added to.
|
||||
- Identify the `action_value` to determine the type of action that the permission allows. Write actions may include `Invoke`, `Update`, or `Put`.
|
||||
-
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1584.007](https://attack.mitre.org/techniques/T1584/007)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,43 @@
|
||||
# Multiple Service Logging Deleted or Stopped
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies the deletion or stopping of multiple service logging actions within AWS. Service logging is a critical security control that provides visibility into the activities and changes within AWS services. Adversaries may attempt to disable or delete service logging to evade detection and cover their tracks. Monitoring for multiple service logging deletions or stops can help identify potential malicious activity and ensure that critical security controls remain intact.
|
||||
|
||||
- **UUID:** `d74f8928-5e46-11ef-9488-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [Multiple Service Logging Deleted or Stopped](../queries/multiple_service_logging_deleted_or_stopped.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider in ("ec2.amazonaws.com","route53resolver.amazonaws.com","s3.amazonaws.com", "cloudtrail.amazonaws.com")
|
||||
and event.action in ("DeleteFlowLogs","DeleteResolverQueryLogConfig", "DeleteTrail", "StopLogging")
|
||||
| eval date = DATE_FORMAT("YYYY-mm-dd", @timestamp)
|
||||
| stats service_logging_delete_count = count(*) by event.provider, event.action, event.outcome, date, aws.cloudtrail.user_identity.arn
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `event.provider` field to identify the service logging action that was deleted or stopped
|
||||
- Use the `event.action` field to identify the specific action that was taken on the service logging
|
||||
- Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions
|
||||
- Review the `source.*` fields for the IP address and geographical location of the request and compare with the user's typical behavior
|
||||
- Check for `CreateFlowLogs`, `CreateResolverQueryLogConfig`, `CreateTrail`, and `StartLogging` API calls to determine if the service logging was recently enabled or started. This could help determine if the deletion was due to maintence or configuration changes
|
||||
- Use ES|QL `stats` function to aggregated on date to identify patterns of multiple service logging deletions or stops
|
||||
-
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1562.008](https://attack.mitre.org/techniques/T1562/008)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,44 @@
|
||||
# S3 Public Bucket Rapid Object Access Attempts
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when an anonymous user, outside of the known AWS IP ranges, makes multiple `GetObject` requests to a public S3 bucket. Rapid access to objects in a public S3 bucket may indicate an adversary attempting to exfiltrate data or perform reconnaissance on the bucket contents.
|
||||
|
||||
- **UUID:** `ef244ca0-5e32-11ef-a8d3-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [S3 Public Bucket Rapid Object Access Attempts](../queries/s3_public_bucket_rapid_object_access_attempts.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "s3.amazonaws.com" and event.action == "GetObject" and cloud.account.id == "anonymous"
|
||||
and NOT CIDR_MATCH(source.ip,
|
||||
"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16",
|
||||
"100.64.0.0/10", "169.254.0.0/16", "127.0.0.0/8",
|
||||
"52.95.0.0/16","54.239.0.0/16", "18.0.0.0/8",
|
||||
"3.0.0.0/8", "35.0.0.0/8")
|
||||
| DISSECT aws.cloudtrail.request_parameters "{%{?bucket_name_key}=%{bucket_name}, %{?host_key}=%{bucket_location}, %{?object_key}=%{bucket_object}}"
|
||||
| STATS s3_bucket_access_count = COUNT(bucket_object) by bucket_name
|
||||
| WHERE s3_bucket_access_count >= 15
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `bucket_name` field to identify the public S3 bucket that the objects were accessed from
|
||||
- Use the `bucket_object` field to identify the objects that were accessed
|
||||
- Review bucket policies and access control lists (ACLs) to ensure that the bucket is not publicly accessible
|
||||
-
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1530](https://attack.mitre.org/techniques/T1530)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,44 @@
|
||||
# Secrets Manager High Frequency of Programmatic GetSecretValue API Calls
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a high frequency of `GetSecretValue` API calls are made to the AWS Secrets Manager service programmatically. The `GetSecretValue` API call retrieves the secret value for a specified secret. High frequency of these calls may indicate an adversary attempting to access sensitive information stored in AWS Secrets Manager via a compromised account or automated tooling.
|
||||
|
||||
- **UUID:** `ef244ca0-5e32-11ef-a8d3-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [Secrets Manager High Frequency of Programmatic GetSecretValue API Calls](../queries/secretsmanager_high_frequency_get_secret_value.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "secretsmanager.amazonaws.com"
|
||||
and event.action == "GetSecretValue"
|
||||
and user_agent.name not in ("Chrome","Firefox","Safari", "Edge", "Brave", "Opera")
|
||||
| dissect aws.cloudtrail.request_parameters "%{}secret:%{secret_value}}"
|
||||
| stats request_counts = count(*) by event.action, aws.cloudtrail.user_identity.arn, source.ip, user_agent.name
|
||||
| sort request_counts asc
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `secret_value` field to identify the secret value that was accessed by adding it to the `stats` statement
|
||||
- Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions
|
||||
- `user_agent.name` field can provide additional context on the tool or application making the API calls. If not `aws-sdk` or known application, investigate further.
|
||||
- Review the `source.*` fields for the IP address and geographical location of the request and compare with the user's typical behavior
|
||||
- The `aws.cloudtrail.user_identity.arn` field can provide additional context on the user making the request and their role permissions. Recent changes to role permissions or unusual logins may indicate a compromised account
|
||||
- `user_agent.name` field can provide additional context on the tool or application making the API calls. If not `aws-sdk` or known application, investigate further.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1555.006](https://attack.mitre.org/techniques/T1555/006)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,58 @@
|
||||
# High Frequency of Service Quotas Multi-Region `GetServiceQuota` API Calls
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a single AWS resource is making `GetServiceQuota` API calls for the EC2 service quota L-1216C47A in more than 10 regions within a 30-second window. Quota code L-1216C47A represents on-demand instances which are used by adversaries to deploy malware and mine cryptocurrency. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance.
|
||||
|
||||
- **UUID:** `7a083b24-6482-11ef-8a8f-f661ea17fbcc`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [High Frequency of Service Quotas Multi-Region `GetServiceQuota` API Calls](../queries/servicequotas_discovery_multi_region_get_service_quota_calls.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
|
||||
// filter for GetServiceQuota API calls
|
||||
| where event.dataset == "aws.cloudtrail" and event.provider = "servicequotas.amazonaws.com" and event.action == "GetServiceQuota"
|
||||
|
||||
// truncate the timestamp to a 30-second window
|
||||
| eval target_time_window = DATE_TRUNC(30 seconds, @timestamp)
|
||||
|
||||
// pre-process the request parameters to extract the service code and quota code
|
||||
| dissect aws.cloudtrail.request_parameters "{%{?service_code_key}=%{service_code}, %{?quota_code_key}=%{quota_code}}"
|
||||
|
||||
// filter for EC2 service quota L-1216C47A (vCPU on-demand instances)
|
||||
| where service_code == "ec2" and quota_code == "L-1216C47A"
|
||||
|
||||
// count the number of unique regions and total API calls within the 30-second window
|
||||
| stats region_count = count_distinct(cloud.region), window_count = count(*) by target_time_window, aws.cloudtrail.user_identity.arn
|
||||
|
||||
// filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window
|
||||
| where region_count >= 10 and window_count >= 10
|
||||
|
||||
// sort the results by time windows in descending order
|
||||
| sort target_time_window desc
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `aws.cloudtrail.user_identity.arn` field to identify the user making the requests and their role permissions
|
||||
- Use the `cloud.region` field to identify the regions where the `GetServiceQuota` API calls were made
|
||||
- Review Elastic Defend alerts for endpoint related activity to identify potential malware or cryptocurrency mining activity
|
||||
- If a valid account compromise is suspected, review source.* fields for the IP address and geographical location of the request and compare with the user's typical behavior
|
||||
- Query for `RunInstances` API calls to determine if new instances were launched using the on-demand instances
|
||||
- If new instances were launched, review the instance metadata and user data scripts for malicious content
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1580](https://attack.mitre.org/techniques/T1580)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,40 @@
|
||||
# Signin Single Factor Console Login via Federated Session
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a user signs in to the AWS Management Console using a federated session and single-factor authentication. Federated sessions are typically used by users who are not directly managed by AWS IAM or have temporary credentials. Single-factor authentication without MFA may indicate a security risk, as MFA adds an additional layer of security to the authentication process. This could also indicate the abuse of STS tokens to bypass MFA requirements.
|
||||
|
||||
- **UUID:** `953b1252-5efd-11ef-a997-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [Signin Single Factor Console Login via Federated Session](../queries/signin_single_factor_console_login_via_federated_session.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "signin.amazonaws.com"
|
||||
and event.action == "GetSigninToken"
|
||||
and aws.cloudtrail.event_type == "AwsConsoleSignIn"
|
||||
and aws.cloudtrail.user_identity.type == "FederatedUser"
|
||||
| dissect aws.cloudtrail.additional_eventdata "{%{?mobile_version_key}=%{mobile_version}, %{?mfa_used_key}=%{mfa_used}}"
|
||||
| where mfa_used == "No"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `aws.cloudtrail.user_identity.type` field to identify the user type making the request. Federated users are typically given temporary credentials to access AWS services.
|
||||
- `aws.cloudtrail.user_identity.session_context.session_issuer.arn` field represents the ARN of the IAM entity that created the federated session. This IAM entity could be compromised and used to create federated sessions.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1078.004](https://attack.mitre.org/techniques/T1078/004)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,40 @@
|
||||
# SSM Rare SendCommand Code Execution by EC2 Instance
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a single `SendCommand` API call is made by an EC2 instance to execute a command via the AWS Systems Manager (SSM) service within the last 7 days. The `SendCommand` API call allows users to remotely execute commands on EC2 instances. Default documents like `AWS-RunPowerShellScript` and `AWS-RunShellScript` are commonly used for this purpose. Adversaries may abuse this API to execute arbitrary commands on compromised EC2 instances.
|
||||
|
||||
- **UUID:** `1844f2d6-5dc7-11ef-b76c-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [SSM Rare SendCommand Code Execution by EC2 Instance](../queries/ssm_rare_sendcommand_code_execution.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "ssm.amazonaws.com" and event.action == "SendCommand"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}documentName=%{document_name},%{}"
|
||||
| dissect aws.cloudtrail.response_elements "%{}instanceIds=[%{instance_id}],%{}"
|
||||
| where document_name in ("AWS-RunPowerShellScript","AWS-RunShellScript") and instance_id != "*"
|
||||
| stats user_command_counts = count(*) by instance_id
|
||||
| where user_command_counts == 1
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- With count 1, this rule will only trigger once for each unique value of the `instance_id` field that has not been seen making this API request within the last 7 days.
|
||||
- Use the `instance_id` field to identify the EC2 instance that executed the command. This instance ID can be used to search for all related activities, focusing on `event.action` and `aws.cloudtrail.request_parameters` fields.
|
||||
- The `parameter` field in the `aws.cloudtrail.request_parameters` contains the command executed by the EC2 instance, however is masked in the query to prevent sensitive data exposure by AWS. Reviewing commands executed on the instance can provide context on the adversary's actions.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1651](https://attack.mitre.org/techniques/T1651)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,38 @@
|
||||
# SSM SendCommand API Used by EC2 Instance
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** An attacker with compromised EC2 instance credentials, may use those credentials to attempt remote code execution against the EC2 instance from which the credentials were compromised via SSM SendCommand API.
|
||||
|
||||
- **UUID:** `38454a64-5b55-11ef-b345-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [SSM SendCommand API Used by EC2 Instance](../queries/ssm_sendcommand_api_used_by_ec2_instance.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "ssm.amazonaws.com"
|
||||
and aws.cloudtrail.user_identity.type == "AssumedRole"
|
||||
and event.action == "SendCommand"
|
||||
and user.id like "*:i-*"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The indicator that this is an EC2 instance assuming a role and performing the action, is the use of the instance id beginning with -i as the session name.
|
||||
- Session name is attached to the end of the `user.id` field and the `aws.cloudtrail.user_identity.arn`.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1651](https://attack.mitre.org/techniques/T1651)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,39 @@
|
||||
# SSM Start Remote Session to EC2 Instance
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a user starts a remote session to an EC2 instance using the AWS Systems Manager (SSM) service. The `StartSession` API call allows users to connect to an EC2 instance using the SSM service. Multiple `StartSession` requests to the same EC2 instance may indicate an adversary attempting to gain access to the instance for malicious purposes. By default on certain AMI types, the SSM agent is pre-installed and running, allowing for easy access to the instance without the need for SSH or RDP.
|
||||
|
||||
- **UUID:** `f9eae44e-5e4d-11ef-878f-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [SSM Start Remote Session to EC2 Instance](../queries/ssm_start_remote_session_to_ec2_instance.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "ssm.amazonaws.com" and event.action == "StartSession"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{target_key}=%{target_instance}}"
|
||||
| stats user_instance_counts = count(*) by target_instance, aws.cloudtrail.user_identity.arn, aws.cloudtrail.user_identity.type, event.outcome
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the `target_instance` field to identify the EC2 instance that the user connected to using the SSM service
|
||||
- Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions
|
||||
- The `event.outcome` field can provide additional context on the success or failure of the `StartSession` request
|
||||
- Identify if the EC2 instance was recently launched by filtering `event.action` field for `RunInstances` API calls. If the instance was not recently launched, investigate further
|
||||
- Sessions started from IAM users may be benign, but sessions where the `aws.cloudtrail.user_identity.type` is `AssumedRole` are suspicious as they indicate instance to instance connections.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1021.007](https://attack.mitre.org/techniques/T1021/007)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,44 @@
|
||||
# STS Suspicious Federated Temporary Credential Request
|
||||
|
||||
---
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Author:** Elastic
|
||||
- **Description:** This hunting query identifies when a user requests temporary federated credentials with a duration greater than 24 hours or with the `AdministratorAccess` policy attached. Federated users are typically given temporary credentials to access AWS services. A duration greater than 24 hours or the `AdministratorAccess` policy attached may indicate an adversary attempting to maintain access to AWS services for an extended period of time or escalate privileges.
|
||||
|
||||
- **UUID:** `3f8393b2-5f0b-11ef-8a25-f661ea17fbce`
|
||||
- **Integration:** [aws.cloudtrail](https://docs.elastic.co/integrations/aws/cloudtrail)
|
||||
- **Language:** `[ES|QL]`
|
||||
- **Source File:** [STS Suspicious Federated Temporary Credential Request](../queries/sts_suspicious_federated_temporary_credential_request.toml)
|
||||
|
||||
## Query
|
||||
|
||||
```sql
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "sts.amazonaws.com"
|
||||
and event.action == "GetFederationToken"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{}name=%{user_name},"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{}durationSeconds=%{duration_requested},"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{}policyArns=[%{policies_applied}]"
|
||||
| eval duration_minutes = to_integer(duration_requested) / 60
|
||||
| where (duration_minutes > 1440) or (policies_applied RLIKE ".*AdministratorAccess.*")
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- If the `aws.cloudtrail.user_identity.arn` does not match the `user_name` field, this may indicate an adversary attempting to escalate privileges by requesting temporary credentials for a different user.
|
||||
- Review `event.outcome` field to identify if the request was successful or failed.
|
||||
- The `aws.cloudtrail.user_identity.session_context.session_issuer.arn` field represents the ARN of the IAM entity that created the federated session. This IAM entity could be compromised and used to create federated sessions. This could indicate the compromised credentials or role used to create the federated session.
|
||||
- An additional query for `event.provider` being `signin.amazonaws.com` and `event.action` being `GetSigninToken` can be used to identify if the temporary credentials are being exchanged for console access.
|
||||
|
||||
## MITRE ATT&CK Techniques
|
||||
|
||||
- [T1550.001](https://attack.mitre.org/techniques/T1550/001)
|
||||
|
||||
## License
|
||||
|
||||
- `Elastic License v2`
|
||||
@@ -0,0 +1,36 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a user makes multiple `DescribeInstances` API calls in multiple regions within a 30-second window. The `DescribeInstances` API call retrieves information about one or more EC2 instances in a region. High frequency of `DescribeInstances` API calls across multiple regions may indicate an adversary attempting to discover the EC2 instances in the account or perform reconnaissance on the EC2 environment.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "e6e78858-6482-11ef-93bd-f661ea17fbcc"
|
||||
name = "High Frequency of EC2 Multi-Region `DescribeInstances` API Calls"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `aws.cloudtrail.user_identity.arn` field to identify the user making the requests and their role permissions",
|
||||
"Use the `cloud.region` field to identify the regions where the `DescribeInstances` API calls were made",
|
||||
"If leveraging SSM, query for `StartSession` API calls to determine if the user is attempting to establish a session with the EC2 instances",
|
||||
"Filter for `event.provider` is `ec2.amazonaws.com` to pivot on unusual activity related to EC2 instances",
|
||||
]
|
||||
mitre = ['T1580']
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
|
||||
// filter for DescribeInstances API calls
|
||||
| where event.dataset == "aws.cloudtrail" and event.provider == "ec2.amazonaws.com" and event.action == "DescribeInstances"
|
||||
|
||||
// truncate the timestamp to a 30-second window
|
||||
| eval target_time_window = DATE_TRUNC(30 seconds, @timestamp)
|
||||
|
||||
// count the number of unique regions and total API calls within the 30-second window
|
||||
| stats region_count = count_distinct(cloud.region), window_count = count(*) by target_time_window, aws.cloudtrail.user_identity.arn
|
||||
|
||||
// filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window
|
||||
| where region_count >= 10 and window_count >= 10
|
||||
|
||||
// sort the results by time windows in descending order
|
||||
| sort target_time_window desc
|
||||
''']
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a user makes EC2 `RunInstances` API calls with a high instance deployment count within a 7-day window. The `RunInstances` API call launches one or more instances in a specified subnet. High instance deployment counts may indicate an adversary attempting to deploy a large number of instances for cryptomining or other malicious activities. This may also aid in identifying potential resource abuse or misconfigurations.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "c3d24ae8-655d-11ef-a990-f661ea17fbcc"
|
||||
name = "High EC2 Instance Deployment Count Attempts by Single User or Role"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `aws.cloudtrail.user_identity.arn` field to identify the user making the requests and their role permissions",
|
||||
"Review `cloud.region` to identify the regions where the `RunInstances` API calls were made",
|
||||
"`subnet_id` should be reviewed to identify the subnet where the instances are being deployed but can also help pivot and narrow down the scope of further queries",
|
||||
"`instance_type` should be reviewed to identify the type of instances being deployed. Cryptomining campaigns often deploy specific instance types to maximize mining efficiency",
|
||||
]
|
||||
mitre = ['T1578.002']
|
||||
query = [
|
||||
'''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "ec2.amazonaws.com"
|
||||
and event.action == "RunInstances"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*minCount.*maxCount.*"
|
||||
| eval date = DATE_FORMAT("YYYY-mm-dd", @timestamp)
|
||||
| dissect aws.cloudtrail.request_parameters "%{}subnetId=%{subnet_id},"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}minCount=%{min_count},"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}maxCount=%{max_count}}]},"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}instanceType=%{instance_type},"
|
||||
| stats
|
||||
target_instance_count = sum(to_integer(max_count) - to_integer(min_count) + 1),
|
||||
user_attempts = count(*) by user.name, date, subnet_id, instance_type, event.outcome
|
||||
| where target_instance_count >= 10
|
||||
'''
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a user modifies the user data attribute of an EC2 instance. The user data attribute is a script that runs when the instance is launched. Modifying the user data attribute could indicate an adversary attempting to gain persistence or execute malicious code on the instance.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "f11ac62c-5f42-11ef-9d72-f661ea17fbce"
|
||||
name = "EC2 Modify Instance Attribute User Data"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `instance_id` field to identify the EC2 instance for which the user data attribute was modified",
|
||||
"Pivot into the EC2 instance if possible and examine the user data script ('/var/lib/cloud/instance/scripts/userdata.txt') for malicious content",
|
||||
"To modify an EC2 instance's user data attribute, the instance must be stopped, therefore check for `StopInstances` API calls in `event.action` field to determine if the instance was stopped and started",
|
||||
"AWS redacts the value of the `user_data` attribute in the CloudTrail logs, so the actual script content will not be visible in the logs",
|
||||
]
|
||||
mitre = ['T1059.009','T1037']
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "ec2.amazonaws.com"
|
||||
and event.action == "ModifyInstanceAttribute"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*attribute=userData.*"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{instance_id_key}=%{instance_id}, %{attribute_key}=%{attribute}, %{value_key}=%{value}}"
|
||||
| stats user_attribute_modify_count = count(*) by aws.cloudtrail.user_identity.arn, event.outcome
|
||||
''']
|
||||
@@ -0,0 +1,28 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a user makes multiple `GetPasswordData` requests for an EC2 instance. The `GetPasswordData` API call retrieves the encrypted administrator password for an instance running Windows. This API call typically only occurs during the initial launch of an instance or when the password is reset. Multiple requests for the same instance may indicate an adversary attempting to escalate privileges or move laterally within the EC2 environment.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "408ba5f6-5db7-11ef-a01c-f661ea17fbce"
|
||||
name = "EC2 Suspicious Get User Password Request"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `instance_id` field to identify the EC2 instance for which the `GetPasswordData` requests were made",
|
||||
"Check for `RunInstances` API calls to determine if the instance was recently launched or if the password was reset",
|
||||
"`aws.cloudtrail.error_code` can provide additional context if the `GetPasswordData` request failed or was denied",
|
||||
"Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions",
|
||||
"If a valid account compromise is suspected, review source.* fields for the IP address and geographical location of the request and compare with the user's typical behavior"
|
||||
]
|
||||
mitre = ['T1552.005']
|
||||
query = [
|
||||
'''
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "ec2.amazonaws.com" and event.action == "GetPasswordData"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{?instance_key}=%{instance_id}}"
|
||||
| stats instance_count = count_distinct(instance_id) by aws.cloudtrail.user_identity.arn
|
||||
| where instance_count >= 2
|
||||
'''
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query gathers data for evidence of an adversary creating an IAM role with an inline attached policy that allows the role to assume another role. This only identifies flags for AWS account IDs that are different from the account ID where the role is being created indicating a potential backdoor IAM role.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "429824b6-60b2-11ef-b0a4-f661ea17fbce"
|
||||
name = "IAM Assume Role Creation with Attached Policy"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Review the `target_account_id` field to identify the account that the role is being created in. This could be another AWS account your organization owns.",
|
||||
"Review `aws.cloudtrail.request_parameters` to identify the role being created and the policy being attached. If the inline policy includes overly permissive permissions such as `AdministratorAccess`, this could be a sign of malicious activity.",
|
||||
"Pivot for `event.action` where the value is `AttachRolePolicy` to identify the policy being attached to the role.",
|
||||
]
|
||||
mitre = ['T1098.003']
|
||||
query = [
|
||||
'''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "iam.amazonaws.com"
|
||||
and event.action == "CreateRole"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*Allow.*"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*sts:AssumeRole.*"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*assumeRolePolicyDocument.*"
|
||||
and aws.cloudtrail.request_parameters RLIKE ".*arn:aws:iam.*"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}AWS\": \"arn:aws:iam::%{target_account_id}:"
|
||||
| where cloud.account.id != target_account_id
|
||||
'''
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query gathers data for evidence of an IAM user activity with no MFA session. This query identifies IAM user activity where the user is not MFA authenticated. Adversaries often target IAM users with weak or no MFA protection to gain unauthorized access to AWS resources after compromising the user's credentials via phishing, third-party breaches, or brute-forcing.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "913a47be-649c-11ef-a693-f661ea17fbcc"
|
||||
name = "IAM User Activity with No MFA Session"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Review the `user_identity.arn` field to identify if activity is sourcing from a browser or programmatically via the AWS CLI or SDK.",
|
||||
"Review aggregated counts of API calls made for suspicious discovery or reconnaissance such as `List*`, `Describe*`, or `Get*` API calls.",
|
||||
]
|
||||
mitre = ['T1078.004']
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.dataset == "aws.cloudtrail"
|
||||
and aws.cloudtrail.user_identity.type == "IAMUser"
|
||||
and aws.cloudtrail.user_identity.session_context.mfa_authenticated == "false"
|
||||
and not user_agent.original in ("cloudformation.amazonaws.com", "application-autoscaling.amazonaws.com", "AWS Internal")
|
||||
and (aws.cloudtrail.user_identity.access_key_id is null or aws.cloudtrail.user_identity.access_key_id == "")
|
||||
| stats activity_counts = count(*) by event.provider, event.action, aws.cloudtrail.user_identity.arn
|
||||
''']
|
||||
@@ -0,0 +1,31 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query gathers data for evidence of an adversary creating a user in AWS and then assigning administrative rights to that user. The `CreateUser` API call to IAM allows the adversary to create the user and then `AttachUserPolicy` where `policy/AdministratorAccess` is identified should match attempts to assign administrative privileges.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "696c3f40-5b54-11ef-b9df-f661ea17fbce"
|
||||
name = "User Creation with Administrator Policy Assigned"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"`aws.cloudtrail.request_parameters` contains the target user the policy is being attached to or the user being created",
|
||||
"`count_distinct` ensures that the user was just created, but also had the administrative policy attached within the respective time window",
|
||||
"There is a chance that timestamps could be out-of-order based on ingestion and event generation in AWS CloudTrail",
|
||||
"The target user's IAM policies should be reviewed to ensure MFA is enabled",
|
||||
"Reviewing the AWS ARN in the event should identify which user made these changes; this user ID should be used to pivot into potential valid account compromise"
|
||||
]
|
||||
mitre = ['T1098.003','T1136.003']
|
||||
query = [
|
||||
'''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "iam.amazonaws.com"
|
||||
and event.outcome == "success"
|
||||
and (event.action == "CreateUser" or
|
||||
(event.action == "AttachUserPolicy" and aws.cloudtrail.request_parameters rlike ".*AdministratorAccess.*"))
|
||||
| stats unique_action_count = count_distinct(event.action) by user.target.name
|
||||
| where unique_action_count == 2
|
||||
'''
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query gathers data for evidence of an adversary adding permissions to a Lambda function that allows write actions. The `AddPermission` API call to Lambda allows the adversary to add permissions to a Lambda function. This query identifies when the `AddPermission` API call is used to add permissions that allow write actions to a Lambda function. Adversaries may use this technique to grant themselves additional permissions to write to a Lambda function, which could be used to execute malicious code or exfiltrate data.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "e3206d1c-64a9-11ef-a642-f661ea17fbcc"
|
||||
name = "Lambda Add Permissions for Write Actions to Function"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Analyze the `principal_id` to identify the entity that the permission is being granted to. Adversaries may use this technique to grant themselves additional permissions.",
|
||||
"Review the `function_name` to identify the Lambda function that the permission is being added to.",
|
||||
"Identify the `action_value` to determine the type of action that the permission allows. Write actions may include `Invoke`, `Update`, or `Put`.",
|
||||
"",
|
||||
]
|
||||
mitre = ['T1584.007']
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "lambda.amazonaws.com"
|
||||
and event.action RLIKE "AddPermission.*"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{?principal_key}=%{principal_id}, %{?function_name_key}=%{function_name}, %{?statement_key}=%{statement_value}, %{?action_key}=lambda:%{action_value}}"
|
||||
| eval write_action = (starts_with(action_value, "Invoke") or starts_with("Update", action_value) or starts_with("Put", action_value))
|
||||
| where write_action == true
|
||||
'''
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies the deletion or stopping of multiple service logging actions within AWS. Service logging is a critical security control that provides visibility into the activities and changes within AWS services. Adversaries may attempt to disable or delete service logging to evade detection and cover their tracks. Monitoring for multiple service logging deletions or stops can help identify potential malicious activity and ensure that critical security controls remain intact.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "d74f8928-5e46-11ef-9488-f661ea17fbce"
|
||||
name = "Multiple Service Logging Deleted or Stopped"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `event.provider` field to identify the service logging action that was deleted or stopped",
|
||||
"Use the `event.action` field to identify the specific action that was taken on the service logging",
|
||||
"Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions",
|
||||
"Review the `source.*` fields for the IP address and geographical location of the request and compare with the user's typical behavior",
|
||||
"Check for `CreateFlowLogs`, `CreateResolverQueryLogConfig`, `CreateTrail`, and `StartLogging` API calls to determine if the service logging was recently enabled or started. This could help determine if the deletion was due to maintence or configuration changes",
|
||||
"Use ES|QL `stats` function to aggregated on date to identify patterns of multiple service logging deletions or stops",
|
||||
""
|
||||
]
|
||||
mitre = ["T1562.008"]
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider in ("ec2.amazonaws.com","route53resolver.amazonaws.com","s3.amazonaws.com", "cloudtrail.amazonaws.com")
|
||||
and event.action in ("DeleteFlowLogs","DeleteResolverQueryLogConfig", "DeleteTrail", "StopLogging")
|
||||
| eval date = DATE_FORMAT("YYYY-mm-dd", @timestamp)
|
||||
| stats service_logging_delete_count = count(*) by event.provider, event.action, event.outcome, date, aws.cloudtrail.user_identity.arn
|
||||
''']
|
||||
@@ -0,0 +1,30 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when an anonymous user, outside of the known AWS IP ranges, makes multiple `GetObject` requests to a public S3 bucket. Rapid access to objects in a public S3 bucket may indicate an adversary attempting to exfiltrate data or perform reconnaissance on the bucket contents.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "ef244ca0-5e32-11ef-a8d3-f661ea17fbce"
|
||||
name = "S3 Public Bucket Rapid Object Access Attempts"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `bucket_name` field to identify the public S3 bucket that the objects were accessed from",
|
||||
"Use the `bucket_object` field to identify the objects that were accessed",
|
||||
"Review bucket policies and access control lists (ACLs) to ensure that the bucket is not publicly accessible",
|
||||
""
|
||||
]
|
||||
mitre = ["T1530"]
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "s3.amazonaws.com" and event.action == "GetObject" and cloud.account.id == "anonymous"
|
||||
and NOT CIDR_MATCH(source.ip,
|
||||
"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16",
|
||||
"100.64.0.0/10", "169.254.0.0/16", "127.0.0.0/8",
|
||||
"52.95.0.0/16","54.239.0.0/16", "18.0.0.0/8",
|
||||
"3.0.0.0/8", "35.0.0.0/8")
|
||||
| DISSECT aws.cloudtrail.request_parameters "{%{?bucket_name_key}=%{bucket_name}, %{?host_key}=%{bucket_location}, %{?object_key}=%{bucket_object}}"
|
||||
| STATS s3_bucket_access_count = COUNT(bucket_object) by bucket_name
|
||||
| WHERE s3_bucket_access_count >= 15
|
||||
''']
|
||||
@@ -0,0 +1,30 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a high frequency of `GetSecretValue` API calls are made to the AWS Secrets Manager service programmatically. The `GetSecretValue` API call retrieves the secret value for a specified secret. High frequency of these calls may indicate an adversary attempting to access sensitive information stored in AWS Secrets Manager via a compromised account or automated tooling.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "ef244ca0-5e32-11ef-a8d3-f661ea17fbce"
|
||||
name = "Secrets Manager High Frequency of Programmatic GetSecretValue API Calls"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `secret_value` field to identify the secret value that was accessed by adding it to the `stats` statement",
|
||||
"Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions",
|
||||
"`user_agent.name` field can provide additional context on the tool or application making the API calls. If not `aws-sdk` or known application, investigate further.",
|
||||
"Review the `source.*` fields for the IP address and geographical location of the request and compare with the user's typical behavior",
|
||||
"The `aws.cloudtrail.user_identity.arn` field can provide additional context on the user making the request and their role permissions. Recent changes to role permissions or unusual logins may indicate a compromised account",
|
||||
"`user_agent.name` field can provide additional context on the tool or application making the API calls. If not `aws-sdk` or known application, investigate further."
|
||||
]
|
||||
mitre = ["T1555.006"]
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "secretsmanager.amazonaws.com"
|
||||
and event.action == "GetSecretValue"
|
||||
and user_agent.name not in ("Chrome","Firefox","Safari", "Edge", "Brave", "Opera")
|
||||
| dissect aws.cloudtrail.request_parameters "%{}secret:%{secret_value}}"
|
||||
| stats request_counts = count(*) by event.action, aws.cloudtrail.user_identity.arn, source.ip, user_agent.name
|
||||
| sort request_counts asc
|
||||
''']
|
||||
@@ -0,0 +1,44 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a single AWS resource is making `GetServiceQuota` API calls for the EC2 service quota L-1216C47A in more than 10 regions within a 30-second window. Quota code L-1216C47A represents on-demand instances which are used by adversaries to deploy malware and mine cryptocurrency. This could indicate a potential threat actor attempting to discover the AWS infrastructure across multiple regions using compromised credentials or a compromised instance.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "7a083b24-6482-11ef-8a8f-f661ea17fbcc"
|
||||
name = "High Frequency of Service Quotas Multi-Region `GetServiceQuota` API Calls"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `aws.cloudtrail.user_identity.arn` field to identify the user making the requests and their role permissions",
|
||||
"Use the `cloud.region` field to identify the regions where the `GetServiceQuota` API calls were made",
|
||||
"Review Elastic Defend alerts for endpoint related activity to identify potential malware or cryptocurrency mining activity",
|
||||
"If a valid account compromise is suspected, review source.* fields for the IP address and geographical location of the request and compare with the user's typical behavior",
|
||||
"Query for `RunInstances` API calls to determine if new instances were launched using the on-demand instances",
|
||||
"If new instances were launched, review the instance metadata and user data scripts for malicious content",
|
||||
]
|
||||
mitre = ['T1580']
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
|
||||
// filter for GetServiceQuota API calls
|
||||
| where event.dataset == "aws.cloudtrail" and event.provider = "servicequotas.amazonaws.com" and event.action == "GetServiceQuota"
|
||||
|
||||
// truncate the timestamp to a 30-second window
|
||||
| eval target_time_window = DATE_TRUNC(30 seconds, @timestamp)
|
||||
|
||||
// pre-process the request parameters to extract the service code and quota code
|
||||
| dissect aws.cloudtrail.request_parameters "{%{?service_code_key}=%{service_code}, %{?quota_code_key}=%{quota_code}}"
|
||||
|
||||
// filter for EC2 service quota L-1216C47A (vCPU on-demand instances)
|
||||
| where service_code == "ec2" and quota_code == "L-1216C47A"
|
||||
|
||||
// count the number of unique regions and total API calls within the 30-second window
|
||||
| stats region_count = count_distinct(cloud.region), window_count = count(*) by target_time_window, aws.cloudtrail.user_identity.arn
|
||||
|
||||
// filter for resources making DescribeInstances API calls in more than 10 regions within the 30-second window
|
||||
| where region_count >= 10 and window_count >= 10
|
||||
|
||||
// sort the results by time windows in descending order
|
||||
| sort target_time_window desc
|
||||
''']
|
||||
@@ -0,0 +1,26 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a user signs in to the AWS Management Console using a federated session and single-factor authentication. Federated sessions are typically used by users who are not directly managed by AWS IAM or have temporary credentials. Single-factor authentication without MFA may indicate a security risk, as MFA adds an additional layer of security to the authentication process. This could also indicate the abuse of STS tokens to bypass MFA requirements.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "953b1252-5efd-11ef-a997-f661ea17fbce"
|
||||
name = "Signin Single Factor Console Login via Federated Session"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `aws.cloudtrail.user_identity.type` field to identify the user type making the request. Federated users are typically given temporary credentials to access AWS services.",
|
||||
"`aws.cloudtrail.user_identity.session_context.session_issuer.arn` field represents the ARN of the IAM entity that created the federated session. This IAM entity could be compromised and used to create federated sessions.",
|
||||
]
|
||||
mitre = ["T1078.004"]
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.provider == "signin.amazonaws.com"
|
||||
and event.action == "GetSigninToken"
|
||||
and aws.cloudtrail.event_type == "AwsConsoleSignIn"
|
||||
and aws.cloudtrail.user_identity.type == "FederatedUser"
|
||||
| dissect aws.cloudtrail.additional_eventdata "{%{?mobile_version_key}=%{mobile_version}, %{?mfa_used_key}=%{mfa_used}}"
|
||||
| where mfa_used == "No"
|
||||
''']
|
||||
@@ -0,0 +1,27 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a single `SendCommand` API call is made by an EC2 instance to execute a command via the AWS Systems Manager (SSM) service within the last 7 days. The `SendCommand` API call allows users to remotely execute commands on EC2 instances. Default documents like `AWS-RunPowerShellScript` and `AWS-RunShellScript` are commonly used for this purpose. Adversaries may abuse this API to execute arbitrary commands on compromised EC2 instances.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "1844f2d6-5dc7-11ef-b76c-f661ea17fbce"
|
||||
name = "SSM Rare SendCommand Code Execution by EC2 Instance"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"With count 1, this rule will only trigger once for each unique value of the `instance_id` field that has not been seen making this API request within the last 7 days.",
|
||||
"Use the `instance_id` field to identify the EC2 instance that executed the command. This instance ID can be used to search for all related activities, focusing on `event.action` and `aws.cloudtrail.request_parameters` fields.",
|
||||
"The `parameter` field in the `aws.cloudtrail.request_parameters` contains the command executed by the EC2 instance, however is masked in the query to prevent sensitive data exposure by AWS. Reviewing commands executed on the instance can provide context on the adversary's actions.",
|
||||
]
|
||||
mitre = ["T1651"]
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "ssm.amazonaws.com" and event.action == "SendCommand"
|
||||
| dissect aws.cloudtrail.request_parameters "%{}documentName=%{document_name},%{}"
|
||||
| dissect aws.cloudtrail.response_elements "%{}instanceIds=[%{instance_id}],%{}"
|
||||
| where document_name in ("AWS-RunPowerShellScript","AWS-RunShellScript") and instance_id != "*"
|
||||
| stats user_command_counts = count(*) by instance_id
|
||||
| where user_command_counts == 1
|
||||
'''
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
An attacker with compromised EC2 instance credentials, may use those credentials to attempt remote code execution against the EC2 instance from which the credentials were compromised via SSM SendCommand API.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "38454a64-5b55-11ef-b345-f661ea17fbce"
|
||||
name = "SSM SendCommand API Used by EC2 Instance"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"The indicator that this is an EC2 instance assuming a role and performing the action, is the use of the instance id beginning with -i as the session name.",
|
||||
"Session name is attached to the end of the `user.id` field and the `aws.cloudtrail.user_identity.arn`."
|
||||
]
|
||||
mitre = ["T1651"]
|
||||
query = [
|
||||
'''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "ssm.amazonaws.com"
|
||||
and aws.cloudtrail.user_identity.type == "AssumedRole"
|
||||
and event.action == "SendCommand"
|
||||
and user.id like "*:i-*"
|
||||
'''
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a user starts a remote session to an EC2 instance using the AWS Systems Manager (SSM) service. The `StartSession` API call allows users to connect to an EC2 instance using the SSM service. Multiple `StartSession` requests to the same EC2 instance may indicate an adversary attempting to gain access to the instance for malicious purposes. By default on certain AMI types, the SSM agent is pre-installed and running, allowing for easy access to the instance without the need for SSH or RDP.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "f9eae44e-5e4d-11ef-878f-f661ea17fbce"
|
||||
name = "SSM Start Remote Session to EC2 Instance"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"Use the `target_instance` field to identify the EC2 instance that the user connected to using the SSM service",
|
||||
"Review the `aws.cloudtrail.user_identity*` fields to identify the user making the requests and their role permissions",
|
||||
"The `event.outcome` field can provide additional context on the success or failure of the `StartSession` request",
|
||||
"Identify if the EC2 instance was recently launched by filtering `event.action` field for `RunInstances` API calls. If the instance was not recently launched, investigate further",
|
||||
"Sessions started from IAM users may be benign, but sessions where the `aws.cloudtrail.user_identity.type` is `AssumedRole` are suspicious as they indicate instance to instance connections."
|
||||
]
|
||||
mitre = ['T1021.007']
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where event.provider == "ssm.amazonaws.com" and event.action == "StartSession"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{target_key}=%{target_instance}}"
|
||||
| stats user_instance_counts = count(*) by target_instance, aws.cloudtrail.user_identity.arn, aws.cloudtrail.user_identity.type, event.outcome
|
||||
''']
|
||||
@@ -0,0 +1,30 @@
|
||||
[hunt]
|
||||
author = "Elastic"
|
||||
description = """
|
||||
This hunting query identifies when a user requests temporary federated credentials with a duration greater than 24 hours or with the `AdministratorAccess` policy attached. Federated users are typically given temporary credentials to access AWS services. A duration greater than 24 hours or the `AdministratorAccess` policy attached may indicate an adversary attempting to maintain access to AWS services for an extended period of time or escalate privileges.
|
||||
"""
|
||||
integration = ["aws.cloudtrail"]
|
||||
uuid = "3f8393b2-5f0b-11ef-8a25-f661ea17fbce"
|
||||
name = "STS Suspicious Federated Temporary Credential Request"
|
||||
language = ["ES|QL"]
|
||||
license = "Elastic License v2"
|
||||
notes = [
|
||||
"If the `aws.cloudtrail.user_identity.arn` does not match the `user_name` field, this may indicate an adversary attempting to escalate privileges by requesting temporary credentials for a different user.",
|
||||
"Review `event.outcome` field to identify if the request was successful or failed.",
|
||||
"The `aws.cloudtrail.user_identity.session_context.session_issuer.arn` field represents the ARN of the IAM entity that created the federated session. This IAM entity could be compromised and used to create federated sessions. This could indicate the compromised credentials or role used to create the federated session.",
|
||||
"An additional query for `event.provider` being `signin.amazonaws.com` and `event.action` being `GetSigninToken` can be used to identify if the temporary credentials are being exchanged for console access."
|
||||
]
|
||||
mitre = ["T1550.001"]
|
||||
query = ['''
|
||||
from logs-aws.cloudtrail-*
|
||||
| where @timestamp > now() - 7 day
|
||||
| where
|
||||
event.dataset == "aws.cloudtrail"
|
||||
and event.provider == "sts.amazonaws.com"
|
||||
and event.action == "GetFederationToken"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{}name=%{user_name},"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{}durationSeconds=%{duration_requested},"
|
||||
| dissect aws.cloudtrail.request_parameters "{%{}policyArns=[%{policies_applied}]"
|
||||
| eval duration_minutes = to_integer(duration_requested) / 60
|
||||
| where (duration_minutes > 1440) or (policies_applied RLIKE ".*AdministratorAccess.*")
|
||||
''']
|
||||
@@ -2,6 +2,26 @@
|
||||
|
||||
Here are the queries currently available:
|
||||
|
||||
## aws
|
||||
- [High Frequency of EC2 Multi-Region `DescribeInstances` API Calls](./aws/docs/ec2_discovery_multi_region_describe_instance_calls.md) (ES|QL)
|
||||
- [High EC2 Instance Deployment Count Attempts by Single User or Role](./aws/docs/ec2_high_instance_deployment_count_attempts.md) (ES|QL)
|
||||
- [EC2 Modify Instance Attribute User Data](./aws/docs/ec2_modify_instance_attribute_user_data.md) (ES|QL)
|
||||
- [EC2 Suspicious Get User Password Request](./aws/docs/ec2_suspicious_get_user_password_request.md) (ES|QL)
|
||||
- [IAM Assume Role Creation with Attached Policy](./aws/docs/iam_assume_role_creation_with_attached_policy.md) (ES|QL)
|
||||
- [IAM User Activity with No MFA Session](./aws/docs/iam_user_activity_with_no_mfa_session.md) (ES|QL)
|
||||
- [User Creation with Administrator Policy Assigned](./aws/docs/iam_user_creation_with_administrator_policy_assigned.md) (ES|QL)
|
||||
- [Lambda Add Permissions for Write Actions to Function](./aws/docs/lambda_add_permissions_for_write_actions_to_function.md) (ES|QL)
|
||||
- [Multiple Service Logging Deleted or Stopped](./aws/docs/multiple_service_logging_deleted_or_stopped.md) (ES|QL)
|
||||
- [S3 Public Bucket Rapid Object Access Attempts](./aws/docs/s3_public_bucket_rapid_object_access_attempts.md) (ES|QL)
|
||||
- [Secrets Manager High Frequency of Programmatic GetSecretValue API Calls](./aws/docs/secretsmanager_high_frequency_get_secret_value.md) (ES|QL)
|
||||
- [High Frequency of Service Quotas Multi-Region `GetServiceQuota` API Calls](./aws/docs/servicequotas_discovery_multi_region_get_service_quota_calls.md) (ES|QL)
|
||||
- [Signin Single Factor Console Login via Federated Session](./aws/docs/signin_single_factor_console_login_via_federated_session.md) (ES|QL)
|
||||
- [SSM Rare SendCommand Code Execution by EC2 Instance](./aws/docs/ssm_rare_sendcommand_code_execution.md) (ES|QL)
|
||||
- [SSM SendCommand API Used by EC2 Instance](./aws/docs/ssm_sendcommand_api_used_by_ec2_instance.md) (ES|QL)
|
||||
- [SSM Start Remote Session to EC2 Instance](./aws/docs/ssm_start_remote_session_to_ec2_instance.md) (ES|QL)
|
||||
- [STS Suspicious Federated Temporary Credential Request](./aws/docs/sts_suspicious_federated_temporary_credential_request.md) (ES|QL)
|
||||
|
||||
|
||||
## linux
|
||||
- [Network Connections with Low Occurrence Frequency for Unique Agent ID](./linux/docs/command_and_control_via_network_connections_with_low_occurrence_frequency_for_unique_agents.md) (ES|QL)
|
||||
- [Unusual File Downloads from Source Addresses](./linux/docs/command_and_control_via_unusual_file_downloads_from_source_addresses.md) (ES|QL)
|
||||
|
||||
@@ -16,1577 +16,14 @@ Adversaries may leverage DNS TXT queries to stage malicious content or exfiltrat
|
||||
## Query
|
||||
|
||||
```sql
|
||||
f```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
m```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
g```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
-```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
v```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
k```
|
||||
|
||||
```sql
|
||||
-```
|
||||
|
||||
```sql
|
||||
*```
|
||||
|
||||
```sql
|
||||
,```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
g```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
-```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
m```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
_```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
-```
|
||||
|
||||
```sql
|
||||
*```
|
||||
|
||||
```sql
|
||||
|
||||
```
|
||||
|
||||
```sql
|
||||
|```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
h```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
h```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
f```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
m```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
v```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
g```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
k```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
|
||||
```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
v```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
(```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
k```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
_```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
q```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
,```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
D```
|
||||
|
||||
```sql
|
||||
N```
|
||||
|
||||
```sql
|
||||
S```
|
||||
|
||||
```sql
|
||||
E```
|
||||
|
||||
```sql
|
||||
v```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
(```
|
||||
|
||||
```sql
|
||||
D```
|
||||
|
||||
```sql
|
||||
N```
|
||||
|
||||
```sql
|
||||
S```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
q```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
)```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
)```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
|
||||
```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
(```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
q```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
T```
|
||||
|
||||
```sql
|
||||
X```
|
||||
|
||||
```sql
|
||||
T```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
T```
|
||||
|
||||
```sql
|
||||
X```
|
||||
|
||||
```sql
|
||||
T```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
)```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
x```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
b```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
!```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
C```
|
||||
|
||||
```sql
|
||||
:```
|
||||
|
||||
```sql
|
||||
\```
|
||||
|
||||
```sql
|
||||
\```
|
||||
|
||||
```sql
|
||||
W```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
\```
|
||||
|
||||
```sql
|
||||
\```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
m```
|
||||
|
||||
```sql
|
||||
3```
|
||||
|
||||
```sql
|
||||
2```
|
||||
|
||||
```sql
|
||||
\```
|
||||
|
||||
```sql
|
||||
\```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
v```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
h```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
x```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
"```
|
||||
|
||||
```sql
|
||||
|
||||
```
|
||||
|
||||
```sql
|
||||
|```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
k```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
x```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
b```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
,```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
_```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
|
||||
```
|
||||
|
||||
```sql
|
||||
|```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
(```
|
||||
|
||||
```sql
|
||||
*```
|
||||
|
||||
```sql
|
||||
)```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
b```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
_```
|
||||
|
||||
```sql
|
||||
i```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
,```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
p```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
.```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
x```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
b```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
|
||||
```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
/```
|
||||
|
||||
```sql
|
||||
*```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
h```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
h```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
l```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
b```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
a```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
j```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
d```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
t```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
y```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
v```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
*```
|
||||
|
||||
```sql
|
||||
/```
|
||||
|
||||
```sql
|
||||
|
||||
```
|
||||
|
||||
```sql
|
||||
|```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
w```
|
||||
|
||||
```sql
|
||||
h```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
o```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
u```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
r```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
n```
|
||||
|
||||
```sql
|
||||
c```
|
||||
|
||||
```sql
|
||||
e```
|
||||
|
||||
```sql
|
||||
s```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
>```
|
||||
|
||||
```sql
|
||||
=```
|
||||
|
||||
```sql
|
||||
```
|
||||
|
||||
```sql
|
||||
5```
|
||||
|
||||
```sql
|
||||
0```
|
||||
|
||||
```sql
|
||||
|
||||
from logs-endpoint.events.network-*, logs-windows.sysmon_operational-*
|
||||
| where host.os.family == "windows" and event.category == "network" and
|
||||
event.action in ("lookup_requested", "DNSEvent (DNS query)") and
|
||||
(dns.question.type == "TXT" or dns.answers.type == "TXT") and process.executable != "C:\\Windows\\system32\\svchost.exe"
|
||||
| keep process.executable, process.entity_id
|
||||
| stats occurrences = count(*) by process.entity_id, process.executable
|
||||
/* threshold can be adjusted to your env */
|
||||
| where occurrences >= 50
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
@@ -14,7 +14,7 @@ notes = [
|
||||
"Pivoting by `process.entity_id` will allow further investigation (parent process, hash, child processes, other network events etc.).",
|
||||
]
|
||||
mitre = [ "T1071", "T1071.004"]
|
||||
query = '''
|
||||
query = ['''
|
||||
from logs-endpoint.events.network-*, logs-windows.sysmon_operational-*
|
||||
| where host.os.family == "windows" and event.category == "network" and
|
||||
event.action in ("lookup_requested", "DNSEvent (DNS query)") and
|
||||
@@ -23,4 +23,4 @@ from logs-endpoint.events.network-*, logs-windows.sysmon_operational-*
|
||||
| stats occurrences = count(*) by process.entity_id, process.executable
|
||||
/* threshold can be adjusted to your env */
|
||||
| where occurrences >= 50
|
||||
'''
|
||||
''']
|
||||
Reference in New Issue
Block a user