T1098.003 Sumo Logic CSE · Sumo

Detect Additional Cloud Roles in Sumo Logic CSE

An adversary may add additional roles or permissions to an adversary-controlled cloud account to maintain persistent access to a tenant. For example, adversaries may update IAM policies in cloud-based environments or add a new global administrator in Office 365 environments. With sufficient permissions, a compromised account can gain almost unlimited access to data and settings, including the ability to reset the passwords of other admins. This account modification may immediately follow account creation or other malicious account activity. Adversaries may also modify existing valid accounts that they have compromised, potentially leading to privilege escalation and lateral movement to additional accounts. In some cases, adversaries may add roles to adversary-controlled accounts outside the victim cloud tenant, allowing external accounts to perform actions inside the victim tenant. Threat groups such as Scattered Spider, LAPSUS$, and Storm-0501 have used this technique to gain persistent administrative access to cloud environments.

MITRE ATT&CK

Tactic
Persistence Privilege Escalation
Technique
T1098 Account Manipulation
Sub-technique
T1098.003 Additional Cloud Roles
Canonical reference
https://attack.mitre.org/techniques/T1098/003/

Sumo Detection Query

Sumo Logic CSE (Sumo)
sql
(_sourceCategory=azure/audit OR _sourceCategory=azure/auditlogs OR _sourceCategory=o365/management/activity OR _sourceCategory=azure/activity)
| json field=_raw "operationName" as az_operation nodrop
| json field=_raw "Operation" as o365_operation nodrop
| json field=_raw "properties.initiatedBy.user.userPrincipalName" as az_initiated_by nodrop
| json field=_raw "UserId" as o365_initiated_by nodrop
| json field=_raw "caller" as az_rbac_caller nodrop
| json field=_raw "properties.targetResources[0].userPrincipalName" as target_user nodrop
| json field=_raw "Target[0].ID" as o365_target nodrop
| json field=_raw "properties.targetResources[0].modifiedProperties[0].newValue" as role_assigned nodrop
| json field=_raw "properties.initiatedBy.user.ipAddress" as az_src_ip nodrop
| json field=_raw "callerIpAddress" as rbac_src_ip nodrop
| json field=_raw "ClientIP" as o365_src_ip nodrop
| json field=_raw "resultType" as az_result nodrop
| json field=_raw "ResultStatus" as o365_result nodrop
| eval operation = if(!isNull(az_operation) AND az_operation != "", az_operation, if(!isNull(o365_operation), o365_operation, ""))
| eval initiated_by = if(!isNull(az_initiated_by) AND az_initiated_by != "", az_initiated_by, if(!isNull(az_rbac_caller) AND az_rbac_caller != "", az_rbac_caller, o365_initiated_by))
| eval target = if(!isNull(target_user) AND target_user != "", target_user, o365_target)
| eval source_ip = if(!isNull(az_src_ip) AND az_src_ip != "", az_src_ip, if(!isNull(rbac_src_ip) AND rbac_src_ip != "", rbac_src_ip, o365_src_ip))
| eval result = if(!isNull(az_result), az_result, o365_result)
| where operation in (
    "Add member to role.",
    "Add eligible member to role.",
    "Add member to role in PIM requested.",
    "Add member to role completed (PIM activation).",
    "Assign directory role to user",
    "Microsoft.Authorization/roleAssignments/write",
    "Microsoft.Authorization/elevateAccess/action",
    "Microsoft.Authorization/roleDefinitions/write"
  )
  OR (toLowerCase(operation) matches "*role*" AND (toLowerCase(operation) matches "*add*" OR toLowerCase(operation) matches "*assign*"))
| where isNull(result) OR result matches "*success*" OR result matches "*succeeded*" OR result = ""
| eval is_high_privilege = if(
    toLowerCase(role_assigned) matches "*global administrator*"
    OR toLowerCase(role_assigned) matches "*privileged role administrator*"
    OR toLowerCase(role_assigned) matches "*security administrator*"
    OR toLowerCase(role_assigned) matches "*exchange administrator*"
    OR toLowerCase(role_assigned) matches "*sharepoint administrator*"
    OR toLowerCase(role_assigned) matches "*user access administrator*"
    OR toLowerCase(role_assigned) matches "*privileged authentication administrator*"
    OR toLowerCase(role_assigned) matches "*hybrid identity administrator*"
    OR toLowerCase(role_assigned) matches "*application administrator*"
    OR toLowerCase(role_assigned) = "owner",
    "true", "false"
  )
| fields _messageTime, operation, initiated_by, target, role_assigned, source_ip, is_high_privilege, result
| sort by _messageTime desc
| sort by is_high_privilege desc
high severity high confidence

Sumo Logic query detecting cloud role assignment operations across Azure Audit Logs, Azure Activity, and Office 365 Management Activity log sources. Normalizes operation names and actor fields across all three source types using conditional eval logic. Flags high-privilege role assignments and filters to successful operations only.

Data Sources

Azure Audit Logs (Sumo Logic Azure source)Azure Activity Logs (Sumo Logic Azure source)Office 365 Management Activity API (Sumo Logic O365 source)

Required Tables

_sourceCategory=azure/audit_sourceCategory=azure/auditlogs_sourceCategory=o365/management/activity_sourceCategory=azure/activity

False Positives & Tuning

  • Azure AD Governance scheduled access review campaigns triggering bulk role re-assignments after certification
  • Infrastructure-as-Code automation via Terraform or Bicep writing RBAC role assignments through service principals during deployments
  • Identity team or help desk staff performing approved IAM change requests within a ticketed change management process
  • Azure AD Connect or Entra Cloud Sync processes generating role-related audit entries during directory synchronization cycles
Download portable Sigma rule (.yml)

Other platforms for T1098.003


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Assign Global Administrator Role to User via Azure AD PowerShell

    Expected signal: Azure AD AuditLogs: OperationName 'Add member to role' with TargetResources containing the target UPN and RoleName 'Global Administrator'. InitiatedBy will show the executing account's UPN and IP address. Event appears in AuditLogs within 5-15 minutes. Unified Audit Log: RecordType 8, Operation 'Add member to role.' with similar details.

  2. Test 2Assign Azure Subscription Owner Role via Az PowerShell (RBAC Escalation)

    Expected signal: AzureActivity log: OperationNameValue 'Microsoft.Authorization/roleAssignments/write' with ActivityStatusValue 'Success', Caller set to the executing account, ResourceId containing the subscription scope and roleAssignment GUID. Event appears in AzureActivity within 2-5 minutes.

  3. Test 3Use elevateAccess API to Gain User Access Administrator at Root Scope

    Expected signal: AzureActivity log: OperationNameValue 'Microsoft.Authorization/elevateAccess/action' with ActivityStatusValue 'Success', Caller set to the Global Admin account. A second event 'Microsoft.Authorization/roleAssignments/write' at scope '/' will also appear as the role is auto-assigned.

  4. Test 4Add External Guest Account to Privileged Role via Microsoft Graph API

    Expected signal: Azure AD AuditLogs: OperationName 'Add member to role' with TargetResources showing the guest account UPN (ending in #EXT# or external domain) and RoleName 'Security Administrator'. InitiatedBy shows the account that executed the Graph API call with its IP address. Graph API calls appear as 'Microsoft Graph' in the InitiatedBy.app field when authenticated via service principal.

Unlock Pro Content

Get the full detection package for T1098.003 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections