let check_actions = AWSCloudTrail
| where (EventName == "CreateKey" or EventName == "PutKeyPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
| extend state=parse_json(parse_json(replace_string(tostring(parse_json(RequestParameters)['policy']),'\\"','"')).['Statement'])
| mv-expand state
| extend Action= tostring(parse_json(state.['Action'][0])), Effect=tostring(parse_json(state.['Effect'])),
Principal=tostring(parse_json(state.['Principal']))
| where (Action == "kms:Encrypt" or Action == "kms:*") and (Effect == 'Allow') and (Principal has "*")
| distinct AwsEventId;
AWSCloudTrail
| where (EventName == "CreateKey" or EventName == "PutKeyPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
| join kind=inner (check_actions) on AwsEventId
| extend timestamp = TimeGenerated
| project-away AwsEventId1
description: |
'Detection of KMS keys where action kms:Encrypt is accessible for everyone (also outside of your organization). This is an idicator that your account is compromised and the attacker uses the encryption key to compromise another company.'
queryFrequency: 1d
status: Available
version: 1.0.2
entityMappings:
- entityType: Account
fieldMappings:
- columnName: AccountName
identifier: Name
- columnName: AccountUPNSuffix
identifier: UPNSuffix
- columnName: RecipientAccountId
identifier: CloudAppAccountId
- entityType: IP
fieldMappings:
- columnName: SourceIpAddress
identifier: Address
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_CreationofEncryptKeysWithoutMFA.yaml
query: |
let check_actions = AWSCloudTrail
| where (EventName == "CreateKey" or EventName == "PutKeyPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
| extend state=parse_json(parse_json(replace_string(tostring(parse_json(RequestParameters)['policy']),'\\"','"')).['Statement'])
| mv-expand state
| extend Action= tostring(parse_json(state.['Action'][0])), Effect=tostring(parse_json(state.['Effect'])),
Principal=tostring(parse_json(state.['Principal']))
| where (Action == "kms:Encrypt" or Action == "kms:*") and (Effect == 'Allow') and (Principal has "*")
| distinct AwsEventId;
AWSCloudTrail
| where (EventName == "CreateKey" or EventName == "PutKeyPolicy") and isempty(ErrorCode) and isempty(ErrorMessage)
| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)
| extend UserName = tostring(split(UserIdentityArn, '/')[-1])
| extend AccountName = case( UserIdentityPrincipalid == "Anonymous", "Anonymous", isempty(UserIdentityUserName), UserName, UserIdentityUserName)
| extend AccountName = iif(AccountName contains "@", tostring(split(AccountName, '@', 0)[0]), AccountName),
AccountUPNSuffix = iif(AccountName contains "@", tostring(split(AccountName, '@', 1)[0]), "")
| join kind=inner (check_actions) on AwsEventId
| extend timestamp = TimeGenerated
| project-away AwsEventId1
requiredDataConnectors:
- connectorId: AWS
dataTypes:
- AWSCloudTrail
tactics:
- Impact
severity: Medium
triggerThreshold: 0
triggerOperator: gt
name: Creating keys with encrypt policy without MFA
id: 454133a7-5427-4a7c-bdc4-0adfa84dda16
relevantTechniques:
- T1485
kind: Scheduled
queryPeriod: 1d