This SOP covers brute force, password spray, and credential stuffing alerts against Entra ID-protected applications (M365, VPN, Entra-joined apps). The most dangerous outcome is a successful login after failed attempts — that check is Phase 3 and must run before containment actions.
Target: attack classified within 10 min; compromise determination within 5 min of classification; CA block applied within 20 min of confirmed malicious activity.
◈ Table of Contents
PHASE 00 — QUICK REFERENCE
METADATA| SOP ID | SOP-02 |
| Owner | T1 SOC Analyst |
| Trigger | Sentinel alert · Entra ID Identity Protection "Unfamiliar sign-in" · CA block spike · MDI brute force alert |
| Time Targets | Attack classified: < 10 min · Compromise check: < 5 min after classification · CA block applied: < 20 min |
| Escalate To | T2 immediately if successful login confirmed after failed attempts → trigger SOP-04 |
| Escalate To | T2 if internal IP is source → potential endpoint compromise → trigger SOP-03 |
| Tools Required | Microsoft Sentinel · portal.azure.com (Entra ID) · security.microsoft.com |
PHASE 01 — ALERT TRIAGE + KQL
TARGET: < 10 MIN- 1From the alert: extract source IP(s), target UPN(s), application targeted (e.g., Azure Portal, VPN, Exchange ActiveSync), time window.
- 2Run KQL to get the full picture of failed attempts by IP — this reveals attack velocity and which accounts were targeted:
- 3Record from results: AccountCount (how many distinct accounts targeted), FailedAttempts (raw volume), DurationMin (attack duration), AppDisplayName (attack surface).
Legacy auth protocols (SMTP, IMAP, MAPI) don't support MFA and are common spray targets. If AppDisplayName shows "Exchange ActiveSync" or "IMAP" → check for legacy auth CA policy gaps immediately.
PHASE 02 — SPRAY VS BRUTE CLASSIFICATION
DETERMINE ATTACK TYPE- 1Brute Force:
AccountCount = 1, many failed attempts. Single account at risk. Reset and lock that account. - 2Password Spray:
AccountCount > 5, <3 attempts per account. Organisation-wide risk — attacker is evading lockout thresholds. Run spray KQL:
- 3Credential Stuffing: High account count AND varied attempt timing (not regular interval). These use breach dump lists. Check if affected accounts exist on known breach dumps via your TI feeds or HaveIBeenPwned Enterprise API.
- 4If source IP is internal: stop — do NOT block in CA yet. That device may be infected with a password sprayer. Go to
Defender XDR → Devices → search IPand trigger SOP-03 for that endpoint.
PHASE 03 — COMPROMISE CHECK
CRITICAL — RUN BEFORE CONTAINMENT- 1Run this KQL immediately — it finds any successful login from the same attacker IP that also had failures. A result here means an account was breached.
- 2If results returned: STOP this SOP. For each compromised UPN → trigger SOP-04 immediately. Do containment in Phase 4 of this SOP in parallel but SOP-04 takes priority.
- 3If no results: no confirmed compromise yet. Continue to Phase 4 containment. The attack is still ongoing or was unsuccessful.
- 4Also check:
portal.azure.com → Microsoft Entra ID → Security → Identity Protection → Risky sign-ins. Sort by Risk level. Any "High" risk sign-in for targeted accounts?
ResultType = "0" from the same IP as the brute force is NOT always a false positive — the attacker may have changed IP for the successful login. Also check UrlClickEvents and DeviceLogonEvents for the targeted accounts across the full time window.
PHASE 04 — CONTAINMENT
ENTRA ID + CONDITIONAL ACCESS- 1Navigate:
portal.azure.com → Microsoft Entra ID → Security → Conditional Access → Named Locations → + New IP ranges location. - 2Name it:
BLOCK-[date]-[IP]-BruteForce. Add the attacking IP or CIDR range. Save. - 3Apply to CA policy:
Conditional Access → Policies → [your block policy]OR create a new policy: Users = All users, Cloud apps = All cloud apps, Conditions → Locations → Include [new named location], Grant = Block access. - 4Set policy to Report-only first for 5 min to confirm no legitimate users come from that IP. Then switch to On.
- 5Verify block is active: re-run the failed logins KQL after 5 min. If the IP is still appearing with new attempts, the CA policy is applied and showing as blocked (
ConditionalAccessStatus = Failure).
- 6Expected result after CA block:
ResultType = 53003(blocked by CA) orConditionalAccessStatus = failure. If still seeingResultType != 0with no CA block status → check policy assignment.
PHASE 05 — ENTRA ID + IDENTITY PROTECTION
IDENTITY HARDENING- 1
portal.azure.com → Microsoft Entra ID → Security → Identity Protection → Risky sign-ins. Find sign-ins from the attacking IP. Select → Confirm sign-in(s) risky. This feeds the risk engine and auto-blocks future attempts by this user if your risk-based CA policy is active. - 2For targeted accounts where lockout occurred:
Entra ID → Users → [user] → Reset password → Require change on next sign-in = ON. This forces a new credential even if the old one was guessed correctly during the attack window. - 3Check MFA enrollment for all targeted accounts:
Entra ID → Users → [user] → Authentication methods. If any account has NO MFA registered → that's a CA policy gap. Note for Phase 6. - 4Check legacy auth exposure:
Entra ID → Sign-in logs → filter: Client app = "Other clients". If any target accounts use legacy auth → these bypass MFA entirely and must be blocked via CA legacy auth policy.
PHASE 06 — TUNING & CLOSE
FINAL STEPS- 1Check:
Entra ID → Security → Conditional Access → Policies— is there an active Sign-in risk policy that blocks Medium and High risk sign-ins with MFA? If not, this is why the attack wasn't auto-blocked. - 2Check: Is there an active CA policy blocking Legacy authentication? If the spray targeted legacy auth apps → that's the gap.
- 3Add attacker IP to Sentinel Watchlist for ongoing monitoring. If the same IP returns: auto-alert fires faster next time.
- 4If source country has zero business presence: consider geo-block CA policy.
Named Locations → Countries location → Add country. Apply as block in CA. - 5Document: attack type, IP(s), accounts targeted, accounts locked, CA policy applied, compromise status (confirmed/not confirmed), gap identified.
- Attacker IP blocked via CA Named Location
- Compromise check KQL run — result documented (compromised / not compromised)
- Targeted accounts: passwords reset, MFA verified
- Identity Protection risk events marked as confirmed
- Legacy auth exposure checked and documented
- CA policy gap (if found) recorded as follow-up remediation item
For additional SOC SOPs covering account compromise, malware triage, and ransomware response, visit cyberhawkthreatintel.com/sops
◈ Stay Connected
Follow CyberHawk Threat Intel for threat intelligence, deployment guides and hands-on SOC tooling content.
"They can't exploit you if you are the Exploit."