Query Details
let _AWSAccounts =
_GetWatchlist("AccountId-AuditAWSAccounts")
| project AccountId, AccountName, Auditors = Auditor, AlertSeverity = Severity, Notes
;
AWSCloudTrail
| where UserIdentityType == "Root"
| summarize
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
SourceIpAddresses = array_sort_asc(make_set_if(SourceIpAddress, isnotempty(SourceIpAddress))),
SessionMfaAuthenticated = make_set_if(SessionMfaAuthenticated, isnotempty(SessionMfaAuthenticated)),
EventNames = array_sort_asc(make_set(EventName)),
ReadOnly = make_set_if(ReadOnly, isnotempty(ReadOnly)),
ManagementEvent = make_set_if(ManagementEvent, isnotempty(ManagementEvent)),
ErrorCodes = make_set_if(ErrorCode, isnotempty(ErrorCode)),
ErrorMessages = make_set_if(ErrorMessage, isnotempty(ErrorMessage)),
UserAgents = make_set_if(UserAgent, isnotempty(UserAgent)),
take_any(UserIdentityType)
by UserIdentityPrincipalid, UserIdentityArn, UserIdentityAccountId, RecipientAccountId
| lookup kind=leftouter _AWSAccounts on $left.UserIdentityAccountId == $right.AccountId
| where not(isnotempty(AccountName) and not(Notes has "[RootActivity]"))
| mv-apply SourceIpAddress = SourceIpAddresses to typeof(string) on (
summarize AddressesList = strcat_array(array_sort_asc(make_set_if(SourceIpAddress, not(SourceIpAddress has ".amazonaws.com"))), '\n\n- ')
)
| extend AlertDescription = strcat(
'This rule detects operations of the root user in AWS accounts, which should be avoided.\n\nThe root user was used in the AWS account "',
iff(isnotempty(AccountName), AccountName, RecipientAccountId),
'".\n\nThe operations were made from the addresses:\n\n- ',
AddressesList,
'\n'
)
| project
StartTime,
EndTime,
UserIdentityAccountName = AccountName,
UserIdentityAccountId,
UserIdentityPrincipalid,
UserIdentityArn,
UserIdentityType,
RecipientAccountId,
SourceIpAddresses,
SessionMfaAuthenticated,
EventNames,
ReadOnly,
ManagementEvent,
ErrorCodes,
ErrorMessages,
UserAgents,
AlertSeverity,
AlertDescription,
Auditors
This query is designed to monitor and report on the activities of the root user in AWS accounts. It first retrieves a list of AWS accounts from a watchlist and then filters the AWS CloudTrail logs for activities performed by the root user.
For each root user activity, it summarizes the start and end times, source IP addresses, whether the session was authenticated with multi-factor authentication, event names, whether the event was read-only or a management event, any error codes or messages, and the user agent.
The query then matches the user identity account ID from the CloudTrail logs with the account ID from the watchlist. If the account name is not empty and there are no notes indicating root activity, the query continues to process the source IP addresses.
Finally, it generates an alert description that includes the account name (or recipient account ID if the account name is not available), and the source IP addresses. The query then projects the summarized data, including the alert severity and auditors from the watchlist.

Jose Sebastián Canós
Released: August 3, 2023
Tables
Keywords
Operators