Creating keys with encrypt policy without MFA
Id | 454133a7-5427-4a7c-bdc4-0adfa84dda16 |
Rulename | Creating keys with encrypt policy without MFA |
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. |
Severity | Medium |
Tactics | Impact |
Techniques | T1485 |
Required data connectors | AWS |
Kind | Scheduled |
Query frequency | 1d |
Query period | 1d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_CreationofEncryptKeysWithoutMFA.yaml |
Version | 1.0.2 |
Arm template | 454133a7-5427-4a7c-bdc4-0adfa84dda16.json |
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
triggerOperator: gt
queryFrequency: 1d
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.'
status: Available
kind: Scheduled
triggerThreshold: 0
requiredDataConnectors:
- connectorId: AWS
dataTypes:
- AWSCloudTrail
version: 1.0.2
queryPeriod: 1d
name: Creating keys with encrypt policy without MFA
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/AWS_CreationofEncryptKeysWithoutMFA.yaml
id: 454133a7-5427-4a7c-bdc4-0adfa84dda16
tactics:
- Impact
relevantTechniques:
- T1485
severity: Medium
entityMappings:
- fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- identifier: CloudAppAccountId
columnName: RecipientAccountId
entityType: Account
- fieldMappings:
- identifier: Address
columnName: SourceIpAddress
entityType: IP
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
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2023-02-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/454133a7-5427-4a7c-bdc4-0adfa84dda16')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/454133a7-5427-4a7c-bdc4-0adfa84dda16')]",
"properties": {
"alertRuleTemplateName": "454133a7-5427-4a7c-bdc4-0adfa84dda16",
"customDetails": null,
"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.'\n",
"displayName": "Creating keys with encrypt policy without MFA",
"enabled": true,
"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\n| where (EventName == \"CreateKey\" or EventName == \"PutKeyPolicy\") and isempty(ErrorCode) and isempty(ErrorMessage)\n| extend state=parse_json(parse_json(replace_string(tostring(parse_json(RequestParameters)['policy']),'\\\\\"','\"')).['Statement'])\n| mv-expand state\n| extend Action= tostring(parse_json(state.['Action'][0])), Effect=tostring(parse_json(state.['Effect'])),\n Principal=tostring(parse_json(state.['Principal']))\n| where (Action == \"kms:Encrypt\" or Action == \"kms:*\") and (Effect == 'Allow') and (Principal has \"*\")\n| distinct AwsEventId;\nAWSCloudTrail\n| where (EventName == \"CreateKey\" or EventName == \"PutKeyPolicy\") and isempty(ErrorCode) and isempty(ErrorMessage)\n| extend UserIdentityArn = iif(isempty(UserIdentityArn), tostring(parse_json(Resources)[0].ARN), UserIdentityArn)\n| extend UserName = tostring(split(UserIdentityArn, '/')[-1])\n| extend AccountName = case( UserIdentityPrincipalid == \"Anonymous\", \"Anonymous\", isempty(UserIdentityUserName), UserName, UserIdentityUserName)\n| extend AccountName = iif(AccountName contains \"@\", tostring(split(AccountName, '@', 0)[0]), AccountName),\n AccountUPNSuffix = iif(AccountName contains \"@\", tostring(split(AccountName, '@', 1)[0]), \"\")\n| join kind=inner (check_actions) on AwsEventId\n| extend timestamp = TimeGenerated\n| project-away AwsEventId1\n",
"queryFrequency": "P1D",
"queryPeriod": "P1D",
"severity": "Medium",
"status": "Available",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Impact"
],
"techniques": [
"T1485"
],
"templateVersion": "1.0.2",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}