AWS Cloud Trail Suspicious AWSCLI Command Execution
Query
let query_frequency = 1h;
let query_period = 2h;
let threshold = 5;
let _ExpectedRoleIdentityRegex = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "AWSAssumedRoleIdentityEventName_Regex" and Auxiliar has "AWS-CLI"
| summarize RegEx = make_set(strcat(SourceResource, ActorPrincipalName))
| extend RegEx = strcat(@"^(", strcat_array(RegEx, "|"), @")$")
);
AWSCloudTrail
| where TimeGenerated > ago(query_period)
| where UserAgent has "aws-cli"
| extend UserIdentityUserName = tostring(split(UserIdentityPrincipalid, ":")[1])
| where not(strcat(SessionIssuerUserName, UserIdentityUserName) matches regex _ExpectedRoleIdentityRegex)
| where EventName matches regex @"Describe|Export|Get|List"
| invoke AWSIdentityRole()
| summarize arg_min(TimeGenerated, *) by Identity, EventName, RecipientAccountId
| as _Events
| join kind=leftsemi (
_Events
// query_period should be 2 * query_frequency
| evaluate activity_counts_metrics(Type, TimeGenerated, ago(query_period), now(), query_frequency, Identity)
| summarize
arg_min(PreviousTimeGenerated = TimeGenerated, PreviousCount = ["count"]),
arg_max(CurrentTimeGenerated = TimeGenerated, CurrentCount = ["count"])
by Identity
| where CurrentTimeGenerated > ago(query_period)
| extend PreviousCount = iff(PreviousTimeGenerated == CurrentTimeGenerated, 0, PreviousCount)
| where (not(PreviousCount > threshold) and CurrentCount > threshold)
or ((CurrentCount - PreviousCount) > threshold)
) on Identity
| project
TimeGenerated,
UserIdentityType,
Identity,
ActorRole,
UserIdentityAccountId,
UserIdentityAccountName,
RecipientAccountId,
RecipientAccountName,
AWSRegion,
SessionCreationDate,
UserIdentityPrincipalid,
UserIdentityArn,
SourceIpAddress,
EventSource,
EventTypeName,
EventName,
ManagementEvent,
ReadOnly,
ErrorCode,
ErrorMessage,
RequestParameters,
ResponseElements,
Resources,
SessionMfaAuthenticated,
UserAgent,
AwsEventIdExplanation
This KQL query is designed to detect unusual AWS CLI activity in AWS CloudTrail logs. Here's a simplified breakdown of what the query does:
-
Setup Variables:
query_frequencyis set to 1 hour.query_periodis set to 2 hours.thresholdis set to 5.
-
Define Expected Role Identities:
- It retrieves a list of expected AWS role identities from a watchlist named "Activity-ExpectedSignificantActivity" that are associated with AWS CLI activity.
- It constructs a regular expression (
_ExpectedRoleIdentityRegex) to match these expected identities.
-
Filter CloudTrail Logs:
- It looks at AWS CloudTrail logs from the last 2 hours.
- It filters for events where the
UserAgentindicates usage of the AWS CLI. - It extracts the username from the
UserIdentityPrincipalid. - It excludes events where the session issuer and user identity match the expected role identities.
-
Identify Specific Events:
- It further filters for events with names that match certain patterns like "Describe", "Export", "Get", or "List".
- It invokes a function
AWSIdentityRole()to enrich the data with role information. - It summarizes the earliest occurrence of each event by identity, event name, and recipient account ID.
-
Detect Anomalous Activity:
- It calculates activity metrics over the last 2 hours, with data points every hour.
- It identifies identities where there is a significant increase in activity count, either exceeding the threshold of 5 or increasing by more than 5 compared to the previous period.
-
Output Results:
- It projects a detailed list of fields related to the detected events, including time, user identity details, event specifics, and any error information.
In essence, this query is designed to flag unusual AWS CLI activity by comparing current activity levels against expected patterns and thresholds, focusing on specific types of AWS API calls.
Details

Jose Sebastián Canós
Released: September 5, 2024
Tables
AWSCloudTrail
Keywords
AWSCloudTrailAWSIdentityRoleActivityUserIdentityEventSessionAccountResourcesRegionErrorRequestResponse
Operators
lettoscalarwherehasextendtostringsplitmatchesregexinvokesummarizearg_minbyasjoinkindleftsemievaluateactivity_counts_metricsagonowiffproject