In the ever-changing landscape of cloud computing, where innovation and complexity intersect, security remains an unwavering priority. Drawing from my experience as a security professional, I have observed the growing sophistication of cybersecurity threats, emphasizing the urgency of implementing robust security measures.
Chronicle Security Operations is designed to be vendor-agnostic, enabling seamless integration across various on-premises and cloud environments, including GCP, Azure, and AWS. While vendor-agnostic capabilities are common in the industry, Chronicle SecOps distinguishes itself by streamlining these processes, focusing on ease of use and efficiency on planetary scale.
As a Google Cloud professional, I am thrilled to share valuable insights and techniques that can enable AWS customers to utilize the robust capabilities of Chronicle SIEM effectively. My friend and colleague, Serhat Gülbetekin, has diligently compiled a list of rules for AWS use cases. These rules are readily available in our GitHub repository, chronicle/detection-rules. I encourage you to explore this resource and leverage it to enhance your security operations.
Below is a listing of the most recently added detections for AWS, focusing on rules that are applicable to AWS GuardDuty and CloudTrail. These detections are aligned with the associated MITRE ATT&CK technique. Please keep in mind that every organization is different; these rules will need to be tested and tuned to fit your environment.
Rule Name |
MITRE ATT&CK Technique |
Description |
Detects an AWS account attempting to leave or being removed from an AWS organization. |
||
Detects API Calls from AWS accounts that are not part of the organization. |
||
Detects when CloudTrail logging is updated, stopped or deleted. |
||
Detects when AWS Config Service is updated, stopped or deleted. |
||
Detects when a user logs into AWS console without MFA. |
||
Detects when a CloudWatch log group is deleted. |
||
Detects when AWS VPC FLow Logs are deleted. |
||
Detects when an Amazon EC2 AMI or Snapshot is shared publicly. |
||
Detects a successful attempt to retrieve the encrypted Administrator password for a Windows EC2 instance. |
||
Detects when an EC2 instance makes a high number of API calls. |
||
Detects modifications to user data script on an EC2 instance. |
||
Detects when an AWS region is enabled or disabled. |
||
Detects excessive successful events within a 5 minute time frame from an IAM User. |
||
Detects when a GuardDuty Detector is disabled or suspended. |
||
Detects when a GuardDuty Detector's publishing destination has been deleted which will prevent the exporting of findings. |
||
Detects when a GuardDuty Detector's trusted or threat intel IP lists are deleted or disabled. |
||
Detects when a high number of failed authentication attempts happen for unknown users. |
||
Detects excessive AccessDenied events within an hour timeframe from an IAM User. |
||
Detects AWS IAM activities associated with the S3 Browser utility. |
||
Detects AWS IAM activities made by AWS EC2 instances to retain access or escalate privileges. |
||
Detects when AWS IAM AdministratorAccess policy is attached to a user, group or role which can be used for privilege escalation. |
||
Detects when the AWS managed policy AWSCompromisedKeyQuarantine has been attached to a user, role, or group. It is applied by the AWS team in the event that an IAM user's credentials has been compromised or publicly exposed. |
||
Detects when a KMS (Key Management Service) key is disabled or scheduled for deletion. |
||
Detects an IAM user attempting to update/modify AWS lambda code. |
||
Detects when an IAM session token is created and used from another IP. |
||
Modify Authentication Process: Multi-Factor Authentication (T1556.006) |
Detects attempts to disable multi-factor authentication for an AWS IAM user. |
|
Modify Authentication Process: Multi-Factor Authentication (T1556.006) |
Detects the registration of a new Multi Factor authentication method for an AWS user. |
|
Detects when an existing password policy is updated or deleted in an AWS account. |
||
Detects when a user creates a new access key for another user and escalates privileges using this newly created access key from the same IP. |
||
Detects when a user creates or updates a login profile for another user and escalates privileges using this new user from the same IP. |
||
Detects when an Amazon RDS Snapshot is shared publicly. |
||
Detects when an AWS S3 bucket is made public using ACL. |
||
Detects when the S3 Public Access Block configuration has been removed from a bucket or an account. |
||
Detects create, update or delete events of a SAML provider in AWS. |
||
Detect when an AWS security group is opened to the world (0.0.0.0/0) or (::/0) |
||
Detects when the Amazon Simple Email Service (SES) has been modified enabling an attacker to propagate phishing emails campaigns. |
||
Detects successful API executions from a Tor exit node. |
||
Detects when an AWS user successfully authenticates from more than one unique IP address within 5 minutes. |
||
Detects successful login after multiple failed attempts. |
||
AWS Unusual Number Of Failed Authentications From The Same Ip |
Detects an unusual number of failed authentications from the same IP for valid users. |
|
Detects when an AWS IAM user creates an AWS Access Key for programmatic calls. |
||
Detects an Amazon EC2 instance or a container attempting to communicate with a black hole IP address. |
||
Detects a brute force activity in an Amazon EC2 or Amazon RDS instance. |
||
Detects Command and control activity in Amazon EC2, AWS Lambda or Amazon EKS Runtimes. |
||
Detects CryptoCurrency activity in Amazon EC2, AWS Lambda or Amazon EKS Runtimes. |
||
Detects a Denial of Service (DoS) activity in an Amazon EC2 instance. |
||
Dynamic Resolution: Domain Generation Algorithms (T1568.002) |
Detects an Amazon EC2 instance or a container querying algorithmically generated domains (DGA). |
|
Detects a malicious or suspicious file on an Amazon EC2 instance or a container workload. |
||
Detects penetration testing activity from known offensive security distros such as Kali Linux, Parrot Linux or Pentoo Linux. |
||
Detects Tor Network activity in an AWS account. |
Let's delve deeper into a couple of detection rules from the list above to gain greater insight into how these rules are crafted using YARA-L.
Lateral movement is a tactic used by attackers once they've gained an initial foothold within a network. In AWS environments, one way this can be achieved is by compromising IAM session tokens. These tokens are used for temporary authentication, and if stolen, an attacker can use them from a different location to escalate their privileges and move further within your cloud infrastructure.
rule aws_lateral_movement_using_iam_session_token {
meta:
author = "Google Cloud Security"
description = "Detect when an IAM session token is created and used from a different IP."
mitre_attack_tactic = "Lateral Movement"
mitre_attack_technique = "Use Alternate Authentication Material"
mitre_attack_url = "https://attack.mitre.org/techniques/T1550/"
mitre_attack_version = "v13.1"
type = "Alert"
data_source = "AWS CloudTrail"
platform = "AWS"
severity = "Medium"
priority = "High"
events:
$accesskey.metadata.vendor_name = "AMAZON"
$accesskey.metadata.product_name = "AWS CloudTrail"
$accesskey.metadata.product_event_type = "GetSessionToken"
$accesskey.security_result.action= "ALLOW"
$accesskey.principal.user.userid = $p_userid
$latmove.metadata.vendor_name = "AMAZON"
$latmove.metadata.product_name = "AWS CloudTrail"
//Different IP address and Same Temp Session Token used
$accesskey.principal.ip != $latmove.principal.ip
$latmove.additional.fields["accessKeyId"] != ""
$accesskey.target.resource.product_object_id = $latmove.additional.fields["accessKeyId"]
$accesskey.metadata.event_timestamp.seconds < $latmove.metadata.event_timestamp.seconds
match:
$p_userid over 1h
outcome:
$risk_score = max(65)
$mitre_attack_tactic = "Lateral Movement"
$mitre_attack_technique = "Use Alternate Authentication Material"
$mitre_attack_technique_id = "T1550"
$event_count = count_distinct($latmove.metadata.id)
$network_http_user_agent = array_distinct($latmove.network.http.user_agent)
$principal_ip = array_distinct($latmove.principal.ip)
$principal_ip_country = array_distinct($latmove.principal.ip_geo_artifact.location.country_or_region)
$principal_ip_state = array_distinct($latmove.principal.ip_geo_artifact.location.state)
$principal_user_display_name = array_distinct($latmove.principal.user.user_display_name)
$dc_principal_user_display_name = count_distinct($latmove.principal.user.user_display_name)
$is_mfa_used = array_distinct($latmove.extensions.auth.auth_details)
$target_resource_name = array_distinct($latmove.target.resource.name)
$target_resource_product_object_id = array_distinct($latmove.target.resource.product_object_id)
$product_event_types = array_distinct($latmove.metadata.product_event_type)
condition:
$accesskey and $latmove
}
The rule's meta section, which includes key-value pairs that describe the rule, offers information for security teams, assisting in categorizing, organizing, and managing detection rules effectively.
In the events section, we define two events variables, each of which represents a set of criteria; $accesskey
and $latmove
.
The$accesskey
event variable captures AWS CloudTrail events with a product event type of 'GetSessionToken'
. The$latmove
event variable collects all AWS CloudTrail events where the accessKeyId is not null.
In our events section, we join two separate collections of AWS CloudTrail logs. We need to ensure that the access key events do not share the sameprincipal.ip
value as the lateral movementprincipal.ip
, which can be achieved using theaccesskey.principal.ip != $latmove.principal.ip
condition. Furthermore, thetarget.resource.product_object_id
in the access key events should match theadditional.fields[“accessKeyId”]
value. Lastly, the access key event must precede the lateral move event, as indicated by the condition$accesskey.metadata.event_timestamp.seconds < latmove.metadata.event_timestamp.second
In the match section, the rule aggregates events with the same user ID$p_userid
(which we captured in the $accesskey
event) involved in both token creation and usage events within a 1-hour time window. The condition section expects both an$accesskey
(token creation) and a corresponding $latmove
(token usage from a different IP) event to exist.
The outcome section allows us to define up to 20 “outcome variables”, with arbitrary names. These outcomes will be stored in the detections generated by the rule and provide context to a security analyst when triage and investigation is needed. Please check out our YARA-L rule style guide if you’re interested in learning more about how we author rules. As you can see below, our implemented rule triggered an alert due to the utilization of an identical session token across various IP addresses.
In the realm of cloud security, particularly within AWS, a notable attack vector involves the exploitation of a misconfigured IAM permission. If an attacker gains this permission, they could create login profiles for new IAM users or overwrite login profiles for existing users. This could grant them elevated privileges within the AWS account, potentially leading to full administrative control.
The YARA-L rule below is designed to detect a privilege escalation within the environment. It focuses on attackers abusing the 'iam:CreateLoginProfile' permission to create new logins and subsequently using those credentials for unauthorized access.
rule aws_privilege_escalation_using_iam_login_profile {
meta:
author = "Google Cloud Security"
description = "Detect when a user creates or updates a login profile for another user and escalates privileges using this new user from the same IP."
mitre_attack_tactic = "Persistence"
mitre_attack_technique = "Cloud Account"
mitre_attack_url = "https://attack.mitre.org/techniques/T1136/003/"
mitre_attack_version = "v13.1"
type = "Alert"
data_source = "AWS CloudTrail"
platform = "AWS"
severity = "High"
priority = "High"
events:
$profile.metadata.vendor_name = "AMAZON"
$profile.metadata.product_name = "AWS CloudTrail"
$profile.metadata.product_event_type = "CreateLoginProfile" or $profile.metadata.product_event_type = "UpdateLoginProfile"
$profile.security_result.action= "ALLOW"
$profile.principal.user.userid = $p_userid
$profile.target.user.userid = $t_userid
$login.metadata.vendor_name = "AMAZON"
$login.metadata.product_name = "AWS CloudTrail"
$login.metadata.event_type = "USER_LOGIN"
$login.metadata.product_event_type = "ConsoleLogin"
$login.security_result.action= "ALLOW"
//Same IP address
$login.principal.ip = $profile.principal.ip
//User created and logged in
$profile.principal.user.user_display_name != $profile.target.user.userid
$login.target.user.user_display_name = $profile.target.user.userid
$profile.metadata.event_timestamp.seconds < $login.metadata.event_timestamp.seconds
match:
$p_userid over 1h
outcome:
$risk_score = max(80)
$mitre_attack_tactic = "Persistence"
$mitre_attack_technique = "Cloud Account"
$mitre_attack_technique_id = "T1136.003"
$event_count = count_distinct($login.metadata.id)
$network_http_user_agent = array_distinct($login.network.http.user_agent)
$principal_ip = array_distinct($login.principal.ip)
$principal_ip_country = array_distinct($login.principal.ip_geo_artifact.location.country_or_region)
$principal_ip_state = array_distinct($login.principal.ip_geo_artifact.location.state)
$principal_user_display_name = array_distinct($login.principal.user.user_display_name)
$dc_principal_user_display_name = count_distinct($login.principal.user.user_display_name)
$is_mfa_used = array_distinct($login.principal.user.attribute.labels["mfaAuthenticated"])
$target_resource_name = array_distinct($login.target.resource.name)
$target_resource_product_object_id = array_distinct($login.target.resource.product_object_id)
condition:
$profile and $login
}
The meta section for YARA-L rules was explained in the earlier example, so let’s go right ahead and take a closer look at the events section for this rule.
This rule is also a multi-event rule where we are joining two different AWS CloudTrail logs together. The $profile
event variable focuses on 'CreateLoginProfile'
or 'UpdateLoginProfile'
events while $login
event variable filters on the event type of 'USER_LOGIN'
with a product event type of 'ConsoleLogin'
where both events have an action of 'ALLOW'
The criteria $login.principal.ip = $profile.principal.ip
ensures that the IP address for both the profile event and the login event are the same, indicating that the login attempt is coming from the same IP address as the profile creation or update event.
To detect if a profile is created or updated by one user but used by another, we expect that the $profile.principal.user.user_display_name != $profile.target.user.userid
. We also want to ensure that the person who logs in is the intended user of the profile by matching login.target.user.user_display_name = $profile.target.user.userid
Finally, the rule ensures that the profile creation or update happens before any login, using the timestamps with $profile.metadata.event_timestamp.seconds < $login.metadata.event_timestamp.seconds
In the match section, the rule looks for events where the same user ID $p_userid is involved in creating or updating a login profile within a 1-hour period. In the condition section, the rule checks for both a profile creation or update event $profile
and a user login event $login
happening together.
The screenshot below displays an alert indicating that a login profile has been successfully created. Additionally, it highlights that the source IP address used to create the login profile is the same as the one being used to access it.
In this post, we focused on how Chronicle can detect suspicious behavior within cloud environments, particularly in AWS. We discussed enhancement of your security posture in AWS through the implementation of a collection of YARA-L rules. Finally, we examined two of these rules in detail, demonstrating their ability to detect potential threats.
If you have any questions or want to discuss Chronicle and AWS security further, please feel free to reach out on the Google Cloud Security Community. Thanks for reading!