Query Details

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,
    AwsEventId

Explanation

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:

  1. Setup Variables:

    • query_frequency is set to 1 hour.
    • query_period is set to 2 hours.
    • threshold is set to 5.
  2. 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.
  3. Filter CloudTrail Logs:

    • It looks at AWS CloudTrail logs from the last 2 hours.
    • It filters for events where the UserAgent indicates 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.
  4. 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.
  5. 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.
  6. 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 profile picture

Jose Sebastián Canós

Released: September 5, 2024

Tables

AWSCloudTrail

Keywords

AWSCloudTrailAWSIdentityRoleActivityUserIdentityEventSessionAccountResourcesRegionErrorRequestResponse

Operators

lettoscalarwherehasextendtostringsplitmatchesregexinvokesummarizearg_minbyasjoinkindleftsemievaluateactivity_counts_metricsagonowiffproject

Actions

GitHub