Privilege Escalation (TA0004)(external, opens in a new tab or window)
Persistence (TA0003)(external, opens in a new tab or window)
text code block:from logs-azure.auditlogs-* metadata _id, _version, _index // role assignments, matching the same operations as the application self-assignment rule | where data_stream.dataset == "azure.auditlogs" and azure.auditlogs.operation_name in ( "Add member to role", "Add member to role outside of PIM (permanent)", "Add member to role in PIM completed (permanent)", "Add member to role in PIM completed (timebound)", "Add eligible member to role in PIM completed (permanent)", "Add eligible member to role in PIM completed (timebound)" ) and event.outcome in ("success", "Success") // the actor can be a user or an application | eval Esql.actor_id = coalesce(azure.auditlogs.properties.initiated_by.user.id, azure.auditlogs.properties.initiated_by.app.servicePrincipalId) | eval Esql.actor_type = case(azure.auditlogs.properties.initiated_by.user.id is not null, "user", "service_principal") // the member is the account among the first two targets; the position differs by operation, and the "outside of PIM" // operation is a PIM alert that records only the role, so it has no member and is dropped below | eval Esql.member_id = case( `azure.auditlogs.properties.target_resources.0.type` in ("User", "ServicePrincipal", "Group"), `azure.auditlogs.properties.target_resources.0.id`, `azure.auditlogs.properties.target_resources.1.type` in ("User", "ServicePrincipal", "Group"), `azure.auditlogs.properties.target_resources.1.id`, null ) | eval Esql.member_type = case( `azure.auditlogs.properties.target_resources.0.type` in ("User", "ServicePrincipal", "Group"), `azure.auditlogs.properties.target_resources.0.type`, `azure.auditlogs.properties.target_resources.1.type` in ("User", "ServicePrincipal", "Group"), `azure.auditlogs.properties.target_resources.1.type`, null ) // one account assigning the role to a different account; self-assignment by an application has its own rule | where Esql.actor_id is not null and Esql.member_id is not null and Esql.actor_id != Esql.member_id // the role name is in a modified property for direct assignments, or the display name of the role target otherwise | eval Esql.role_name_raw = coalesce( case(`azure.auditlogs.properties.target_resources.0.modified_properties.0.display_name` == "Role.DisplayName", `azure.auditlogs.properties.target_resources.0.modified_properties.0.new_value`, null), case(`azure.auditlogs.properties.target_resources.0.modified_properties.1.display_name` == "Role.DisplayName", `azure.auditlogs.properties.target_resources.0.modified_properties.1.new_value`, null), case(`azure.auditlogs.properties.target_resources.0.modified_properties.2.display_name` == "Role.DisplayName", `azure.auditlogs.properties.target_resources.0.modified_properties.2.new_value`, null), case(`azure.auditlogs.properties.target_resources.0.modified_properties.3.display_name` == "Role.DisplayName", `azure.auditlogs.properties.target_resources.0.modified_properties.3.new_value`, null), case(`azure.auditlogs.properties.target_resources.0.type` == "Role", `azure.auditlogs.properties.target_resources.0.display_name`, null), case(`azure.auditlogs.properties.target_resources.1.type` == "Role", `azure.auditlogs.properties.target_resources.1.display_name`, null) ) | eval Esql.role_name = replace(Esql.role_name_raw, "\"", "") // privileged roles: every built-in role marked PRIVILEGED in the Microsoft Entra built-in roles reference, plus other // built-in roles with administrative control over major Entra and Microsoft 365 services or access to tenant data. // Matched by exact role name, not by pattern. | where to_lower(Esql.role_name) in ( // marked PRIVILEGED by Microsoft "agent id administrator", "ai administrator", "ai reader", "application administrator", "application developer", "attribute provisioning administrator", "attribute provisioning reader", "authentication administrator", "authentication extensibility administrator", "authentication extensibility password administrator", "b2c ief keyset administrator", "cloud application administrator", "cloud device administrator", "conditional access administrator", "directory writers", "domain name administrator", "entra soc identity responder", "external identity provider administrator", "global administrator", "global reader", "helpdesk administrator", "hybrid identity administrator", "identity governance administrator", "intune administrator", "lifecycle workflows administrator", "partner tier1 support", "partner tier2 support", "password administrator", "privileged authentication administrator", "privileged role administrator", "security administrator", "security operator", "security reader", "tenant governance administrator", "user administrator", // not marked privileged by Microsoft, but with administrative control over major services "attribute assignment administrator", "authentication policy administrator", "cloud app security administrator", "compliance administrator", "directory synchronization accounts", "dynamics 365 administrator", "exchange administrator", "external id user flow administrator", "global secure access administrator", "groups administrator", "knowledge administrator", "microsoft 365 backup administrator", "microsoft 365 migration administrator", "on premises directory sync account", "power platform administrator", "sharepoint administrator", "skype for business administrator", "teams administrator", "teams telephony administrator", "windows 365 administrator", "yammer administrator", // additional roles: mailbox permissions, local administrator on joined devices (current and previous display // name), delegated partner access to the tenant, and approval of Microsoft support access to customer data "exchange recipient administrator", "azure ad joined device local administrator", "microsoft entra joined device local administrator", "customer delegated admin relationship administrator", "customer lockbox access approver", "entra customer lockbox approver", // legacy display name of Global Administrator "company administrator" ) | drop Esql.role_name_raw | keep @timestamp, Esql.*, azure.*, event.*, cloud.*, related.*, tags, source.*, agent.*, client.*, _id, _version, _index, data_stream.namespace
Install detection rules in Elastic Security
Detect Entra ID Privileged Role Assigned to Another Account in the Elastic Security detection engine by installing this rule into your Elastic Stack.
To setup this rule, check out the installation guide for Prebuilt Security Detection Rules(external, opens in a new tab or window).