
CyberSecurity
Offensive security research, identity plane attack simulation, and defensive control validation for institutional cloud infrastructure. This exercise reconstructs a 7-stage identity takeover against Microsoft Entra ID — from cached credential abuse to complete MFA destruction — in under 60 seconds.
The Identity Plane Is the New Perimeter
Traditional network security assumed a hard perimeter — firewalls, DMZs, VPNs. Cloud-native infrastructure has dissolved that boundary entirely. In a world where every resource is accessible via API, the identity plane is the only perimeter that matters.
A single compromised Global Administrator token grants unrestricted access to every user, every application, every piece of data in the tenant. No firewall rule stops it. No network segmentation contains it. The attack surface is the entire Microsoft Graph API — and it responds in milliseconds.
This red team exercise proves that a complete identity takeover — credential rotation, session destruction, privilege escalation, and total MFA wipe — can be executed in under 60 seconds with 12 API calls. The only defense is detection depth and response speed.

15+ years architecting cloud infrastructure across Azure, AWS, and GCP — including identity systems securing $40B+ in assets under management. My security practice spans Entra ID hardening, zero-trust architecture, Conditional Access engineering, workload identity federation, and offensive security validation through red team exercises like this one. I build the systems that protect institutional capital, then I break them to prove they hold.
7-Stage Identity Kill Chain
Each stage was derived from a real operational engagement against a Microsoft Entra ID tenant. Click any stage to expand the technical detail, MITRE mapping, and risk assessment.

MITRE ATT&CK Mapping
| Stage | Technique ID | Technique | Tactic |
|---|---|---|---|
| 1 | T1528 | Steal Application Access Token | Credential Access |
| 1 | T1550.001 | Use Alternate Auth Material | Defense Evasion |
| 2 | T1087.004 | Cloud Account Discovery | Discovery |
| 3 | T1098.001 | Additional Cloud Credentials | Persistence |
| 4 | T1531 | Account Access Removal | Impact |
| 5 | T1098.003 | Additional Cloud Roles | Privilege Escalation |
| 5 | T1484.002 | Domain Trust Modification | Defense Evasion |
| 6 | T1556.006 | Modify MFA Process | Credential Access |
| 7 | T1070.004 | Indicator Removal | Defense Evasion |
Recommended Defensive Controls
12 controls across three implementation horizons, designed to break this kill chain at multiple stages simultaneously.

Immediate
Week 1- Sentinel alert on revokeSignInSessions by non-break-glass admins
- Sentinel alert on authentication method deletion events
- Alert on addPassword → removePassword within 1 hour on same application
- Out-of-band SMS/email to user when password is administratively reset
Short-Term
Month 1- PIM enforcement for all Global Administrator operations
- Workload Identity Conditional Access restricting SPN to known IP ranges
- Application permission baseline with drift alerting
- Encrypted CLI token cache on all admin workstations
Medium-Term
Quarter- Administrative Units for scoped authentication method management
- Continuous Access Evaluation (CAE) strict mode for privileged users
- App consent policy blocking self-service UserAuthenticationMethod.* grants
- Documented break-glass recovery SOP for zero-MFA state
KQL Detection Queries
Production-ready Microsoft Sentinel analytics rules designed to detect each phase of this attack chain. Deploy directly to your Sentinel workspace.
Password Reset + Session Revocation Correlation
Detects admin password reset followed by session revocation within 10 minutes — the signature of Stages 3-4.
let timeWindow = 10m;
AuditLogs
| where OperationName == "Reset user password"
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
| extend Initiator = tostring(InitiatedBy.user.userPrincipalName)
| where Initiator != TargetUser
| join kind=inner (
AuditLogs
| where OperationName == "Revoke sign-in sessions"
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
) on TargetUser
| where TimeGenerated1 between (TimeGenerated .. (TimeGenerated + timeWindow))Bulk MFA Method Deletion
Fires when 2+ authentication methods are deleted from a single user within 15 minutes.
AuditLogs
| where OperationName has "Delete"
and OperationName has "authentication method"
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
| summarize MethodsDeleted = count(),
Methods = make_set(OperationName)
by TargetUser, bin(TimeGenerated, 15m)
| where MethodsDeleted >= 2Ephemeral Client Secret Pattern
Catches the create-then-destroy credential pattern used in Stage 5-7.
let timeWindow = 2h;
AuditLogs
| where OperationName == "Add service principal credentials"
| extend AppId = tostring(TargetResources[0].id)
| join kind=inner (
AuditLogs
| where OperationName == "Remove service principal credentials"
| extend AppId = tostring(TargetResources[0].id)
) on AppId
| where TimeGenerated1 between (TimeGenerated .. (TimeGenerated + timeWindow))
| project AddTime = TimeGenerated, RemoveTime = TimeGenerated1,
Duration = TimeGenerated1 - TimeGeneratedFull Kill Chain — Composite Detection
Correlates password reset + session revocation + MFA deletion within 30 minutes. CRITICAL severity.
let timeWindow = 30m;
let passwordResets = AuditLogs
| where OperationName == "Reset user password";
let sessionRevocations = AuditLogs
| where OperationName == "Revoke sign-in sessions";
let mfaDeletions = AuditLogs
| where OperationName has "Delete"
and OperationName has "authentication method";
passwordResets
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
| join kind=inner (
sessionRevocations
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
) on TargetUser
| join kind=inner (
mfaDeletions
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
) on TargetUser
| where TimeGenerated1 between (TimeGenerated .. (TimeGenerated + timeWindow))
and TimeGenerated2 between (TimeGenerated .. (TimeGenerated + timeWindow))
| extend AlertSeverity = "CRITICAL"