NRT First access credential added to Application or Service Principal where no credential was present
Id | b6988c32-4f3b-4a45-8313-b46b33061a74 |
Rulename | NRT First access credential added to Application or Service Principal where no credential was present |
Description | This will alert when an admin or app owner account adds a new credential to an Application or Service Principal where there was no previous verify KeyCredential associated. If a threat actor obtains access to an account with sufficient privileges and adds the alternate authentication material triggering this event, the threat actor can now authenticate as the Application or Service Principal using this credential. Additional information on OAuth Credential Grants can be found in RFC 6749 Section 4.4 or https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow For further information on AuditLogs please see https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-audit-activities. |
Categories | |
Author | |
Severity | Medium |
Tactics | DefenseEvasion |
Techniques | T1550.001 |
Required data connectors | AzureActiveDirectory |
Kind | NRT |
Source | |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Detections/AuditLogs/nrt_FirstAppOrServicePrincipalCredential.yaml |
Version | 1.0.2 |
Arm template | b6988c32-4f3b-4a45-8313-b46b33061a74.json |
AuditLogs
| where OperationName has_any ("Add service principal", "Certificates and secrets management")
| where Result =~ "success"
| where tostring(InitiatedBy.user.userPrincipalName) has "@" or tostring(InitiatedBy.app.displayName) has "@"
| extend targetDisplayName = tostring(TargetResources[0].displayName)
| extend targetId = tostring(TargetResources[0].id)
| extend targetType = tostring(TargetResources[0].type)
| extend keyEvents = TargetResources[0].modifiedProperties
| mv-expand keyEvents
| where keyEvents.displayName =~ "KeyDescription"
| extend new_value_set = parse_json(tostring(keyEvents.newValue))
| extend old_value_set = parse_json(tostring(keyEvents.oldValue))
| where old_value_set == "[]"
| mv-expand new_value_set
| parse new_value_set with * "KeyIdentifier=" keyIdentifier:string ",KeyType=" keyType:string ",KeyUsage=" keyUsage:string ",DisplayName=" keyDisplayName:string "]" *
| where keyUsage == "Verify" or keyUsage == ""
| extend UserAgent = iff(AdditionalDetails[0].key == "User-Agent",tostring(AdditionalDetails[0].value),"")
| extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName),tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
| extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))
// The below line is currently commented out but Microsoft Sentinel users can modify this query to show only Application or only Service Principal events in their environment
//| where targetType =~ "Application" // or targetType =~ "ServicePrincipal"
| project-away new_value_set, old_value_set
| project-reorder TimeGenerated, OperationName, InitiatingUserOrApp, InitiatingIpAddress, UserAgent, targetDisplayName, targetId, targetType, keyDisplayName, keyType, keyUsage, keyIdentifier, CorrelationId, TenantId
version: 1.0.2
threatAnalysisTactics:
- DefenseEvasion
threatAnalysisTechniques:
- T1550.001
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
entityMappings:
- fieldMappings:
- columnName: InitiatingUserOrApp
identifier: FullName
entityType: Account
- fieldMappings:
- columnName: InitiatingIpAddress
identifier: Address
entityType: IP
kind: NRT
id: b6988c32-4f3b-4a45-8313-b46b33061a74
severity: Medium
query: |
AuditLogs
| where OperationName has_any ("Add service principal", "Certificates and secrets management")
| where Result =~ "success"
| where tostring(InitiatedBy.user.userPrincipalName) has "@" or tostring(InitiatedBy.app.displayName) has "@"
| extend targetDisplayName = tostring(TargetResources[0].displayName)
| extend targetId = tostring(TargetResources[0].id)
| extend targetType = tostring(TargetResources[0].type)
| extend keyEvents = TargetResources[0].modifiedProperties
| mv-expand keyEvents
| where keyEvents.displayName =~ "KeyDescription"
| extend new_value_set = parse_json(tostring(keyEvents.newValue))
| extend old_value_set = parse_json(tostring(keyEvents.oldValue))
| where old_value_set == "[]"
| mv-expand new_value_set
| parse new_value_set with * "KeyIdentifier=" keyIdentifier:string ",KeyType=" keyType:string ",KeyUsage=" keyUsage:string ",DisplayName=" keyDisplayName:string "]" *
| where keyUsage == "Verify" or keyUsage == ""
| extend UserAgent = iff(AdditionalDetails[0].key == "User-Agent",tostring(AdditionalDetails[0].value),"")
| extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName),tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
| extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))
// The below line is currently commented out but Microsoft Sentinel users can modify this query to show only Application or only Service Principal events in their environment
//| where targetType =~ "Application" // or targetType =~ "ServicePrincipal"
| project-away new_value_set, old_value_set
| project-reorder TimeGenerated, OperationName, InitiatingUserOrApp, InitiatingIpAddress, UserAgent, targetDisplayName, targetId, targetType, keyDisplayName, keyType, keyUsage, keyIdentifier, CorrelationId, TenantId
metadata:
tags:
- Solorigate
- NOBELIUM
description: |
'This will alert when an admin or app owner account adds a new credential to an Application or Service Principal where there was no previous verify KeyCredential associated.
If a threat actor obtains access to an account with sufficient privileges and adds the alternate authentication material triggering this event, the threat actor can now authenticate as the Application or Service Principal using this credential.
Additional information on OAuth Credential Grants can be found in RFC 6749 Section 4.4 or https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
For further information on AuditLogs please see https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-audit-activities.'
author:
name: Samik Roy
name: NRT First access credential added to Application or Service Principal where no credential was present
relevantTechniques:
- T1550.001
tactics:
- DefenseEvasion
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/AuditLogs/nrt_FirstAppOrServicePrincipalCredential.yaml
support:
tier: Community
categories:
domains:
- Security - Others
- Identity
source:
kind: Community
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/b6988c32-4f3b-4a45-8313-b46b33061a74')]",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/b6988c32-4f3b-4a45-8313-b46b33061a74')]",
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
"kind": "Nrt",
"apiVersion": "2022-11-01",
"properties": {
"displayName": "NRT First access credential added to Application or Service Principal where no credential was present",
"description": "'This will alert when an admin or app owner account adds a new credential to an Application or Service Principal where there was no previous verify KeyCredential associated.\nIf a threat actor obtains access to an account with sufficient privileges and adds the alternate authentication material triggering this event, the threat actor can now authenticate as the Application or Service Principal using this credential.\nAdditional information on OAuth Credential Grants can be found in RFC 6749 Section 4.4 or https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow\nFor further information on AuditLogs please see https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-audit-activities.'\n",
"severity": "Medium",
"enabled": true,
"query": "AuditLogs\n| where OperationName has_any (\"Add service principal\", \"Certificates and secrets management\")\n| where Result =~ \"success\"\n| where tostring(InitiatedBy.user.userPrincipalName) has \"@\" or tostring(InitiatedBy.app.displayName) has \"@\"\n| extend targetDisplayName = tostring(TargetResources[0].displayName)\n| extend targetId = tostring(TargetResources[0].id)\n| extend targetType = tostring(TargetResources[0].type)\n| extend keyEvents = TargetResources[0].modifiedProperties\n| mv-expand keyEvents\n| where keyEvents.displayName =~ \"KeyDescription\"\n| extend new_value_set = parse_json(tostring(keyEvents.newValue))\n| extend old_value_set = parse_json(tostring(keyEvents.oldValue))\n| where old_value_set == \"[]\"\n| mv-expand new_value_set\n| parse new_value_set with * \"KeyIdentifier=\" keyIdentifier:string \",KeyType=\" keyType:string \",KeyUsage=\" keyUsage:string \",DisplayName=\" keyDisplayName:string \"]\" *\n| where keyUsage == \"Verify\" or keyUsage == \"\"\n| extend UserAgent = iff(AdditionalDetails[0].key == \"User-Agent\",tostring(AdditionalDetails[0].value),\"\")\n| extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName),tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))\n| extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))\n// The below line is currently commented out but Microsoft Sentinel users can modify this query to show only Application or only Service Principal events in their environment\n//| where targetType =~ \"Application\" // or targetType =~ \"ServicePrincipal\"\n| project-away new_value_set, old_value_set\n| project-reorder TimeGenerated, OperationName, InitiatingUserOrApp, InitiatingIpAddress, UserAgent, targetDisplayName, targetId, targetType, keyDisplayName, keyType, keyUsage, keyIdentifier, CorrelationId, TenantId\n",
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"DefenseEvasion"
],
"techniques": [
"T1550.001"
],
"alertRuleTemplateName": "b6988c32-4f3b-4a45-8313-b46b33061a74",
"customDetails": null,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"identifier": "FullName",
"columnName": "InitiatingUserOrApp"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"identifier": "Address",
"columnName": "InitiatingIpAddress"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/AuditLogs/nrt_FirstAppOrServicePrincipalCredential.yaml",
"support": {
"tier": "Community"
},
"author": {
"name": "Samik Roy"
},
"tags": [
"Solorigate",
"NOBELIUM"
],
"categories": {
"domains": [
"Security - Others",
"Identity"
]
},
"source": {
"kind": "Community"
},
"threatAnalysisTechniques": [
"T1550.001"
],
"threatAnalysisTactics": [
"DefenseEvasion"
],
"templateVersion": "1.0.2"
}
}
]
}