Query Details

Added Sensitive Api Permissions

Query

  // Added Sensitive API Permissions from unprivileged user
  // Modified version from "Admin promotion after Role Management Application Permission Grant" (f80d951a-eddc-4171-b9d0-d616bb83efdc) and "Service Principal Assigned App Role With Sensitive Access" (dd78a122-d377-415a-afe9-f22e08d2112c)
  let SensitiveMsGraphPermissions = externaldata(EAMTierLevel: string, Category: string, APIPermission: string)["https://raw.githubusercontent.com/Cloud-Architekt/AzurePrivilegedIAM/main/Classification/Classification_MsGraphPermissions.json"] with(format='multijson');
  AuditLogs
  | where TimeGenerated >ago(90d)
  | where LoggedByService =~ "Core Directory"
  | where Category =~ "ApplicationManagement"
  | where AADOperationType =~ "Assign"  
  | where OperationName == "Add app role assignment to service principal"
  | where Result =~ "success"
  | mv-expand TargetResources
  | mv-expand TargetResources.modifiedProperties
  | extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
  | where displayName_ =~ "AppRole.Value"
  | extend AppRole = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue)))
  | extend InitiatingUserOrApp = iff(isnotempty(InitiatedBy.user.userPrincipalName),tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
  | extend InitiatingUserOrAppId = iff(isnotempty(InitiatedBy.user.id),tostring(InitiatedBy.user.id), tostring(InitiatedBy.app.id))
  | extend InitiatingIpAddress = iff(isnotempty(InitiatedBy.user.ipAddress), tostring(InitiatedBy.user.ipAddress), tostring(InitiatedBy.app.ipAddress))
  | extend UserAgent = iff(AdditionalDetails[0].key == "User-Agent",tostring(AdditionalDetails[0].value),"")
  | extend AddedPermission = replace_string(tostring(TargetResources_modifiedProperties.newValue),'"','')
  | join kind=inner ( SensitiveMsGraphPermissions | project AddedPermissionClassification = EAMTierLevel, AddedPermissionCategory = Category, APIPermission ) on $left.AddedPermission == $right.APIPermission
  | mv-expand TargetResources.modifiedProperties | where TargetResources_modifiedProperties.displayName == "ServicePrincipal.ObjectID" | extend ServicePrincipalObjectID = replace_string(tostring(TargetResources_modifiedProperties.newValue),'"','')
  | mv-expand TargetResources.modifiedProperties | where TargetResources_modifiedProperties.displayName == "ServicePrincipal.DisplayName" | extend ServicePrincipalDisplayName = replace_string(tostring(TargetResources_modifiedProperties.newValue),'"','')
  | mv-expand TargetResources.modifiedProperties | where TargetResources_modifiedProperties.displayName == "ServicePrincipal.AppId" | extend ServicePrincipalAppId = replace_string(tostring(TargetResources_modifiedProperties.newValue),'"','')
  | join kind=inner (
    PrivilegedEAM_CL
        | where TimeGenerated > ago(14d)
        | summarize arg_max(TimeGenerated, *) by ObjectId
        | extend InitiatingUserOrAppClassification = iff(isnotempty(parse_json(Classification)), parse_json(Classification), "UserAccess")
        | project ObjectId, ObjectAdminTierLevel, ObjectAdminTierLevelName, InitiatingUserOrAppClassification
    ) on $left.InitiatingUserOrAppId == $right.ObjectId
//| where parse_json(tostring(parse_json(InitiatingUserOrAppClassification))) !contains AddedPermissionClassification
| project-reorder OperationName, ServicePrincipalObjectID, ServicePrincipalDisplayName, ServicePrincipalAppId, InitiatingUserOrApp, InitiatingUserOrAppId, InitiatingIpAddress, InitiatingUserOrAppClassification, UserAgent, AddedPermission, AddedPermissionClassification, AddedPermissionCategory

Explanation

This query retrieves information about sensitive API permissions that have been added by an unprivileged user. It filters audit logs for app role assignments to service principals in the Core Directory category and checks for successful results. It then expands and extracts relevant properties from the TargetResources field, such as display name, app role, initiating user or app details, and user agent. The query joins this data with a list of sensitive Microsoft Graph permissions to classify the added permissions. It also joins with another dataset to determine the admin tier level of the initiating user or app. Finally, it projects and reorders the relevant fields for analysis.

Details

Thomas Naunheim profile picture

Thomas Naunheim

Released: September 16, 2023

Tables

AuditLogsSensitiveMsGraphPermissionsPrivilegedEAM_CL

Keywords

Devices,Intune,User,APIPermission,Category,EAMTierLevel,AuditLogs,TimeGenerated,LoggedByService,CoreDirectory,ApplicationManagement,AADOperationType,Assign,OperationName,Addapproleassignmenttoserviceprincipal,Result,TargetResources,modifiedProperties,displayName_,AppRole,InitiatingUserOrApp,InitiatingUserOrAppId,InitiatingIpAddress,User-Agent,AdditionalDetails,AddedPermission,SensitiveMsGraphPermissions,EAMTierLevel,Category,APIPermission,ServicePrincipal.ObjectID,ServicePrincipal.DisplayName,ServicePrincipal.AppId,PrivilegedEAM_CL,ObjectId,ObjectAdminTierLevel,ObjectAdminTierLevelName,InitiatingUserOrAppClassification,Classification,parse_json,contains,project-reorder

Operators

where|>ago()=~===~===~===~==mv-expandextendiff()isnotempty()tostring()parse_json()replace_string()joinonprojectsummarizearg_max()bywhere>ago()extendproject-reorder

Actions