Something feels off. Several users in the organisation have recently gained access to sensitive resources through what appears to be legitimate Azure AD group membership. The security team flagged an anomaly — a dynamic group seems to have been quietly reconfigured. Using Azure AD logs, Microsoft Sentinel, and Graph API traces, the task is to piece together the timeline, identify what changed, who made it, and determine whether this was an administrative misstep or a calculated privilege escalation attempt via dynamic group manipulation.
The first step in any Sentinel investigation is understanding what log sources are available. Querying the available tables reveals the relevant custom log tables for this environment:

MTSummaryMessage_CL, InteractiveSignIns_CL, AuditLogs_CL, and UnifiedAuditLogs_CL are all present. The investigation works through each in sequence.
Before pivoting to auth logs, establishing what delivered the attack is critical. Inspecting the schema of the Exchange message trace table:
MTSummaryMessage_CL
| getschema

With the schema understood, projecting the relevant fields across all messages reveals the lure:
MTSummaryMessage_CL
| project OriginTimestampUtc, SenderAddress, RecipientStatus, MessageSubject, OriginalClientIp
| order by OriginTimestampUtc asc

The results surface a phishing email with subject “Security code” — a classic device-code phishing lure. The sender domain is a typosquatted address designed to impersonate a legitimate MFA or authentication notification:

Device-code phishing works by tricking the target into entering an attacker-controlled device code at microsoft.com/devicelogin. The victim authenticates legitimately, and the attacker polls the token endpoint to receive a valid access token — no credential capture required, and no MFA bypass needed.
With the lure confirmed, the next step is finding the authentication event where the stolen token was used. Checking the schema first:
InteractiveSignIns_CL
| getschema
The AuthenticationProtocol field is present. Filtering for device-code flows:
InteractiveSignIns_CL
| where AuthenticationProtocol contains "device"
| project DateUTC, Username, AuthenticationProtocol, UserAgent, IPaddress, IPaddressseenbyresource
| order by DateUTC asc

This returns the first attacker sign-in: timestamp 2025-07-11 16:50 UTC, authentication protocol deviceCode, client application Mobile Apps and Desktop Clients, and source IP 18.194.240.33. The IP is geographically anomalous relative to the victim organisation — consistent with the attacker polling the token from their own infrastructure.
Following the token redemption, the attacker moved quickly to establish a persistent foothold by inviting an external guest identity. Schema exploration via limit 1 was necessary to understand the field layout before constructing a useful query:
AuditLogs_CL | limit 1

This surfaces the guest account creation event. The invited UPN is nilafe8896_hosintoy.com#EXT#@cydefstg.onmicrosoft.com — a guest identity sourced from the attacker-controlled domain hosintoy.com.
With the guest account created, the attacker’s next move was to satisfy the membership rules of a target dynamic group by setting specific attributes on the guest account. Attempts against AuditLogs_CL with Update user operations returned incomplete field data, so the investigation moved to UnifiedAuditLogs_CL:
UnifiedAuditLogs_CL
| where Operation contains "Update user" and AuditData contains "nilafe8896"
| project CreationDate, Operation, AuditData
| order by CreationDate asc

The AuditData JSON reveals the full modification record. The actor rudolph.emma@compliantsecure.store — the compromised account — updated two attributes on the guest:
Country: "" → "US"Department: "" → "Operations"The User-Agent recorded in additionalDetails is WindowsPowerShell/5.1.14393.7155 — the attacker used PowerShell to make the Graph API call, consistent with scripted post-compromise automation.
These two attributes were deliberately chosen to match the membership rule of the target dynamic group. Dynamic groups in Azure AD automatically enrol any user whose attributes satisfy the configured rule expression — no manual group add required, and the actor recorded for the membership change is the Azure AD engine itself rather than the human attacker.
With the groomed attributes in place, the dynamic group membership engine fired automatically. Querying for the group add event:
UnifiedAuditLogs_CL
| where Operation contains "add member" and AuditData contains "nilafe8896"
| project CreationDate, Operation, AuditData
| order by CreationDate asc
| limit 2

The guest account was auto-enrolled into the Operations group. The actor recorded is Microsoft Approval Management — the Azure AD service principal responsible for dynamic group evaluation. This is the key evasion characteristic of this technique: no human actor appears in the group membership audit log, making it difficult to attribute without tracing back through the attribute modification chain.
| Phase | Action |
|---|---|
| Delivery | Device-code phishing email (“Security code”) sent from typosquatted domain |
| Initial Access | Victim authenticates; attacker redeems device code, obtains access token |
| Token Use | Attacker signs in from 18.194.240.33 at 2025-07-11 16:50 UTC |
| Persistence | Guest account nilafe8896_hosintoy.com#EXT# invited via compromised account |
| Attribute Grooming | Country=US, Department=Operations set via PowerShell/Graph API |
| Privilege Escalation | Guest auto-enrolled into Operations dynamic group by Azure AD engine |
| Type | Value |
|---|---|
| Phishing Subject | Security code |
| Attacker IP | 18[.]194[.]240[.]33 |
| Compromised Account | rudolph[.]emma@compliantsecure[.]store |
| Guest UPN | nilafe8896_hosintoy[.]com#EXT#@cydefstg[.]onmicrosoft[.]com |
| Attacker Domain | hosintoy[.]com |
| Tenant ID | f41b1015-d95d-467b-b488-86114e178cc4 |
| First Token Use (UTC) | 2025-07-11 16:50 |
| Auth Protocol | deviceCode |
| Client App | Mobile Apps and Desktop Clients |
| Target Group | Operations |
| Technique | ID | Description |
|---|---|---|
| Spearphishing Link | T1566.002 | Device-code phishing email delivered to lure victim into authenticating |
| Valid Accounts: Cloud Accounts | T1078.004 | Compromised Azure AD account used to perform all post-access actions |
| Create Account: Cloud Account | T1136.003 | External guest identity created for persistent access |
| Account Manipulation: Additional Cloud Roles | T1098.003 | Guest account attributes groomed to satisfy dynamic group membership rule |
| Domain Policy Modification: Cloud Groups | T1484.002 | Dynamic group manipulation used to auto-elevate guest into privileged group |
Block device-code flow at the Conditional Access layer. Device-code authentication has no legitimate use case for most end users. A Conditional Access policy blocking urn:ietf:params:oauth:grant-type:device_code as an authentication flow eliminates this attack vector entirely before the token is ever redeemed.
Alert on guest account creation followed by attribute modification. The two-step pattern — invite guest, then immediately set Country and Department — is a high-fidelity signal for dynamic group grooming. A Sentinel analytic rule correlating Add user and Update user operations on the same guest UPN within a short window is an effective detection.
Audit dynamic group membership rules. Dynamic groups are powerful but opaque. Documenting every group’s membership rule expression and alerting on rule changes (Operation: Update group) reduces the window in which an attacker can abuse misconfigured or overly broad rules without detection.
Monitor Microsoft Approval Management as an actor. Because the group add event records the Azure AD service principal rather than a human actor, teams that only alert on human-initiated group membership changes will miss this entirely. Audit logs showing Microsoft Approval Management adding a recently-created guest to a privileged group should be treated as a high-priority alert.
Restrict guest invitations to authorised inviters. The Azure AD guest invitation policy should be scoped to a named set of administrators. If rudolph.emma had no legitimate reason to invite external users, this restriction would have blocked the persistence mechanism before the guest account existed.