Query Details

AWS Cloud Trail Aws Iam Accessdenied Discovery Events

Query

let query_frequency = 1h;
let query_period = 2h;
let threshold = 5;
let _ExpectedErrorCodes = dynamic(["AccessDenied", "InvalidAccessException", "Client.UnauthorizedOperation", "AuthorizerConfigurationException"]);
let _ExpectedRoleIdentityRegex = toscalar(
    _GetWatchlist("Activity-ExpectedSignificantActivity")
    | where Activity == "AWSAssumedRoleIdentityEventName_Regex" and Auxiliar has_any (_ExpectedErrorCodes)
    | summarize RegEx = make_set(strcat(SourceResource, ActorPrincipalName))
    | extend RegEx = strcat(@"^(", strcat_array(RegEx, "|"), @")$")
);
let _ExpectedUsers = toscalar(
    _GetWatchlist("Activity-ExpectedSignificantActivity")
    | where Activity == "AWSIAMUser" and Auxiliar has_any (_ExpectedErrorCodes)
    | summarize make_list(ActorPrincipalName)
);
let _ExpectedIPAddresses = toscalar(
    _GetWatchlist("IP-Vendors")
    | where Notes has "[Proxy]"
    | summarize make_list(IPAddress)
);
AWSCloudTrail
| where TimeGenerated > ago(query_period)
| where ErrorCode in ("AccessDenied", "InvalidAccessException", "Client.UnauthorizedOperation", "AuthorizerConfigurationException")
| where not(UserIdentityArn in (_ExpectedUsers))
| extend UserIdentityUserName = tostring(split(UserIdentityPrincipalid, ":")[1])
| where not(ErrorCode in (_ExpectedErrorCodes) and strcat(SessionIssuerUserName, UserIdentityUserName) matches regex _ExpectedRoleIdentityRegex)
| summarize arg_min(TimeGenerated, *) by UserIdentityArn, EventName, ErrorCode
| 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, UserIdentityArn)
    | summarize
        arg_min(PreviousTimeGenerated = TimeGenerated, PreviousCount = ["count"]),
        arg_max(CurrentTimeGenerated = TimeGenerated, CurrentCount = ["count"])
        by UserIdentityArn
    | where CurrentTimeGenerated > ago(query_period)
    | extend PreviousCount = iff(PreviousTimeGenerated == CurrentTimeGenerated, 0, PreviousCount)
    | where (not(PreviousCount > threshold) and CurrentCount > threshold)
        or ((CurrentCount - PreviousCount) > threshold)
    ) on UserIdentityArn
| where not(isnotempty(parse_ipv4(SourceIpAddress)) and ipv4_is_in_any_range(SourceIpAddress, _ExpectedIPAddresses))
| invoke AWSIdentityRole()
| project
    TimeGenerated,
    UserIdentityType,
    Identity,
    ActorRole,
    UserIdentityAccountId,
    UserIdentityAccountName,
    RecipientAccountId,
    RecipientAccountName,
    SessionCreationDate,
    UserIdentityPrincipalid,
    UserIdentityArn,
    SourceIpAddress,
    EventSource,
    EventTypeName,
    EventName,
    ManagementEvent,
    ReadOnly,
    ErrorCode,
    ErrorMessage,
    RequestParameters,
    ResponseElements,
    Resources,
    SessionMfaAuthenticated,
    UserAgent,
    AwsEventId

Explanation

The query is filtering and analyzing AWS CloudTrail logs to identify significant activity that may indicate unauthorized access or errors. It uses predefined watchlists to define expected error codes, user identities, and IP addresses. The query then filters out events that match the expected error codes, user identities, and IP addresses. Finally, it projects specific fields from the filtered events for further analysis.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: February 14, 2024

Tables

AWSCloudTrail

Keywords

AWSCloudTrail,TimeGenerated,ErrorCode,UserIdentityArn,EventName,_ExpectedErrorCodes,_ExpectedRoleIdentityRegex,_ExpectedUsers,_ExpectedIPAddresses,UserIdentityPrincipalid,SessionIssuerUserName,UserIdentityUserName,SessionCreationDate,UserIdentityType,Identity,ActorRole,UserIdentityAccountId,UserIdentityAccountName,RecipientAccountId,RecipientAccountName,SourceIpAddress,EventSource,EventTypeName,ManagementEvent,ReadOnly,ErrorMessage,RequestParameters,ResponseElements,Resources,SessionMfaAuthenticated,UserAgent,AwsEventId

Operators

|=letdynamictoscalar|whereandhas_anysummarizemake_setstrcatstrcat_arrayextendmatches regexarg_minarg_maxbyjoin kind=leftsemievaluateactivity_counts_metricsnowiffisnotemptyparse_ipv4ipv4_is_in_any_rangeinvokeproject

Actions