Skip to main content

Review update (September 26, 2026): The merged rules run every 15 minutes, retain their correlation lookbacks, and gate on recent ingestion from either relevant side. Rule 2 merges duplicate representations of a successful sign-in while retaining the latest ingestion and any unclear risk. Per-result alerting maps user/app/IP context without global suppression. The checker preserves multiline query arguments and verbatim UPN literals and bounds incident lookup in UTC. Active-role preflight includes transitive groups and scoped assignments; normal lab users may require independent administrator review and the explicit skip switch because role enumeration itself needs provider permissions. Do not grant an admin role to the lab user to make this check pass. Historical April evidence remains unchanged; these are offline/source checks.

Source maintenance reviewed September 26, 2026: this updated source passed its offline and CI checks. Historical tenant evidence in the companion article retains its original dates; no fresh tenant deployment or detection result is asserted here.

Overview

This lab provides two disabled-by-default Microsoft Sentinel analytics rules, three Defender XDR hunts, a neutral synthetic replay, and an optional no-secret public client for lab-owned sign-in telemetry. It covers the 50199-to-success pattern, reviewed app/user/IP contexts with risk checks, post-token mailbox behavior, and device registration after token issuance.

Start Here

  1. Read the companion article for the attack model and tuning guidance.
  2. Open the canonical GitHub repository.
  3. Treat the README and tracked KQL files as the operational source of truth. Follow their exact preflight, deployment, replay or telemetry, verification, and cleanup sequence.

The included replay data is the preferred starting point. Do not conduct phishing against real users, and do not use the optional app outside a dedicated lab identity.

Reviewed Implementation Notes

  • The device-registration hunt now uses the documented exact action and registering-user GUID in RawEventData.Target[1].ID; RawEventData.ObjectId remains UPN context. Ten event-shape fixtures and semantic analysis pass, without a new tenant query. Confirm the raw schema in your own retained events.

  • scripts/manage-sentinel-rules.ps1 is the only supported rule lifecycle path. It preflights two fixed workspace-scoped rule IDs and both display names, refuses foreign collisions, and requires the exact local provenance manifest plus ownership suffix before updating or removing existing rules.

  • Both scheduled rules deploy disabled. Explicit enablement requires -EnableRules -Execute -Confirm after you verify SigninLogs, run the tracked KQL manually, and review any exact app/user/IP context exceptions.

  • Rule 1 retains every matching correlation, including Azure CLI and Azure PowerShell. Rule 2 starts with no exceptions; suppression requires an exact immutable app ID, immutable user ID, and source IP plus explicitly clear risk data. Elevated, hidden, missing, or unknown risk remains visible, including risk on the preceding interrupt. Neither display names nor client IDs alone suppress results.

  • The Sentinel Bicep template loads the tracked KQL files directly, so the deployable rules cannot silently drift from the reviewed query sources.

  • The telemetry checker requires the exact lab client ID and user UPN. Optional RunId matches the complete marker via an OR-based UserAgent fallback that can still broaden results; omit it for the strict identity predicate. Disabled rules do not create incidents.

  • The optional Graph Bicep app requires a fresh GUID-suffixed uniqueName and the existing dedicated labUserObjectId. It requires user assignment and creates no loopback redirect URI. Cleanup reads the exact tenant, client, application-object, service-principal, and uniqueName values, validates every ownership tag before deletion, never searches by display name or UPN, and never deletes users.

  • The July 25 review was offline: both Bicep templates compiled, every PowerShell entry point parsed, mocked collision and ownership failures stopped before mutation, and the canonical and bundled lab copies matched byte for byte. It did not create or delete a tenant object, approve a device code, or run a live cloud query.

  • The September 4 client-context change passed offline fixtures, source contracts, and Bicep compilation. Those checks did not execute KQL in Sentinel or repeat the historical tenant validation.