NRT Login to AWS Management Console without MFA
Id | 0ee2aafb-4500-4e36-bcb1-e90eec2f0b9b |
Rulename | NRT Login to AWS Management Console without MFA |
Description | Multi-Factor Authentication (MFA) helps you to prevent credential compromise. This alert identifies logins to the AWS Management Console without MFA. You can limit this detection to trigger for administrative accounts if you do not have MFA enabled on all accounts. This is done by looking at the eventName ConsoleLogin and if the AdditionalEventData field indicates MFA was NOT used and the ResponseElements field indicates NOT a Failure. Thereby indicating that a non-MFA login was successful. |
Severity | Low |
Tactics | DefenseEvasion PrivilegeEscalation Persistence InitialAccess |
Techniques | T1078 |
Required data connectors | AWS AWSS3 |
Kind | NRT |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/NRT_AWS_ConsoleLogonWithoutMFA.yaml |
Version | 1.0.3 |
Arm template | 0ee2aafb-4500-4e36-bcb1-e90eec2f0b9b.json |
AWSCloudTrail
| where EventName =~ "ConsoleLogin"
| extend MFAUsed = tostring(parse_json(AdditionalEventData).MFAUsed), LoginResult = tostring(parse_json(ResponseElements).ConsoleLogin)
| where MFAUsed !~ "Yes" and LoginResult !~ "Failure"
| where SessionIssuerUserName !contains "AWSReservedSSO"
| 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]), "")
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by EventName, EventTypeName, LoginResult, MFAUsed, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityAccountId, UserIdentityPrincipalid, UserAgent,
UserIdentityUserName, SessionMfaAuthenticated, SourceIpAddress, AWSRegion
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Amazon Web Services/Analytic Rules/NRT_AWS_ConsoleLogonWithoutMFA.yaml
status: Available
name: NRT Login to AWS Management Console without MFA
entityMappings:
- fieldMappings:
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- identifier: CloudAppAccountId
columnName: RecipientAccountId
entityType: Account
- fieldMappings:
- identifier: Address
columnName: SourceIpAddress
entityType: IP
kind: NRT
severity: Low
id: 0ee2aafb-4500-4e36-bcb1-e90eec2f0b9b
requiredDataConnectors:
- dataTypes:
- AWSCloudTrail
connectorId: AWS
- dataTypes:
- AWSCloudTrail
connectorId: AWSS3
description: |
'Multi-Factor Authentication (MFA) helps you to prevent credential compromise. This alert identifies logins to the AWS Management Console without MFA.
You can limit this detection to trigger for administrative accounts if you do not have MFA enabled on all accounts.
This is done by looking at the eventName ConsoleLogin and if the AdditionalEventData field indicates MFA was NOT used and the ResponseElements field indicates NOT a Failure. Thereby indicating that a non-MFA login was successful.'
tactics:
- DefenseEvasion
- PrivilegeEscalation
- Persistence
- InitialAccess
query: |
AWSCloudTrail
| where EventName =~ "ConsoleLogin"
| extend MFAUsed = tostring(parse_json(AdditionalEventData).MFAUsed), LoginResult = tostring(parse_json(ResponseElements).ConsoleLogin)
| where MFAUsed !~ "Yes" and LoginResult !~ "Failure"
| where SessionIssuerUserName !contains "AWSReservedSSO"
| 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]), "")
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by EventName, EventTypeName, LoginResult, MFAUsed, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityAccountId, UserIdentityPrincipalid, UserAgent,
UserIdentityUserName, SessionMfaAuthenticated, SourceIpAddress, AWSRegion
relevantTechniques:
- T1078
version: 1.0.3
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/0ee2aafb-4500-4e36-bcb1-e90eec2f0b9b')]",
"kind": "NRT",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/0ee2aafb-4500-4e36-bcb1-e90eec2f0b9b')]",
"properties": {
"alertRuleTemplateName": "0ee2aafb-4500-4e36-bcb1-e90eec2f0b9b",
"customDetails": null,
"description": "'Multi-Factor Authentication (MFA) helps you to prevent credential compromise. This alert identifies logins to the AWS Management Console without MFA.\nYou can limit this detection to trigger for administrative accounts if you do not have MFA enabled on all accounts.\nThis is done by looking at the eventName ConsoleLogin and if the AdditionalEventData field indicates MFA was NOT used and the ResponseElements field indicates NOT a Failure. Thereby indicating that a non-MFA login was successful.'\n",
"displayName": "NRT Login to AWS Management Console 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/NRT_AWS_ConsoleLogonWithoutMFA.yaml",
"query": "AWSCloudTrail\n| where EventName =~ \"ConsoleLogin\"\n| extend MFAUsed = tostring(parse_json(AdditionalEventData).MFAUsed), LoginResult = tostring(parse_json(ResponseElements).ConsoleLogin)\n| where MFAUsed !~ \"Yes\" and LoginResult !~ \"Failure\"\n| where SessionIssuerUserName !contains \"AWSReservedSSO\"\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| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by EventName, EventTypeName, LoginResult, MFAUsed, RecipientAccountId, AccountName, AccountUPNSuffix, UserIdentityAccountId, UserIdentityPrincipalid, UserAgent,\n UserIdentityUserName, SessionMfaAuthenticated, SourceIpAddress, AWSRegion\n",
"severity": "Low",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"DefenseEvasion",
"InitialAccess",
"Persistence",
"PrivilegeEscalation"
],
"techniques": [
"T1078"
],
"templateVersion": "1.0.3"
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}