Attacks on Identity
How attackers go after identities and how to stop them: password spraying, credential stuffing, MFA fatigue and token theft, pass-the-hash, Kerberoasting and golden tickets, explained to recognize and defend.
Why identity is the main target
Firewalls, patching and endpoint protection have made exploiting software harder. An account that works needs no exploit at all: the attacker signs in like an employee, and every action looks legitimate. That is why identity is often called the new security perimeter, and why so many incidents start with a valid account (see attack vectors).
Identity attacks come in two families. Cloud and sign-in attacks target the front door: passwords, MFA prompts and the tokens an identity provider issues. Directory attacks happen after a first foothold inside the network: they abuse how Active Directory (AD), NTLM and Kerberos store and use secrets (see Kerberos and NTLM) to move from one workstation to the whole domain. A typical intrusion uses both.
The attacks at a glance
MITRE ATT&CK is the shared catalog of attacker techniques (see MITRE ATT&CK). Its IDs let a detection rule, an incident report and a vendor's documentation refer to exactly the same thing.
| Attack | ATT&CK ID | What it abuses | Main defense |
|---|---|---|---|
| Password spraying | T1110.003 | Common passwords, accounts without MFA | MFA everywhere, banned-password lists, smart lockout |
| Credential stuffing | T1110.004 | Passwords reused from other breaches | MFA, breached-password checks |
| MFA fatigue | T1621 | Users approving push prompts | Number matching, phishing-resistant MFA |
| Adversary-in-the-middle phishing | T1557 | A proxy between user and real sign-in page | Phishing-resistant MFA, compliant-device policies |
| Session cookie theft | T1539 | Cookies issued after sign-in | Token binding, short sessions, revocation |
| Application access token theft | T1528 | OAuth tokens via consent or device code phishing | Consent policies, block device code flow where unused |
| Pass-the-hash | T1550.002 | NTLM password hashes in memory | LAPS, tiering, Credential Guard, less NTLM |
| Pass-the-ticket | T1550.003 | Kerberos tickets in memory | Tiering, Protected Users, short ticket lifetimes |
| Kerberoasting | T1558.003 | Weak service account passwords | gMSA/dMSA, long random passwords, AES only |
| AS-REP roasting | T1558.004 | Accounts without Kerberos preauthentication | Require preauthentication on every account |
| Golden ticket | T1558.001 | The KRBTGT account's key | Protect tier 0, reset KRBTGT twice after compromise |
| DCSync | T1003.006 | Directory replication rights | Restrict replication rights, monitor non-DC replication |
Password attacks
Password spraying
Guessing many passwords for one account trips the lockout policy after a handful of tries. Password spraying turns this around: the attacker tries one or two very common passwords (a season plus a year, the company name plus "123") against hundreds or thousands of accounts, slowly, so no single account reaches the lockout threshold. In a large organization, someone almost always has one of those passwords.
A well-documented case: Microsoft reported that the group it calls Midnight Blizzard got into its corporate environment, detected on 12 January 2024, through a password spray against a legacy, non-production test tenant account that had no MFA. The attacker used few attempts and residential proxy addresses to stay under the radar, then abused a legacy test OAuth application with elevated access to Microsoft's corporate environment, used it to create new apps with full mailbox access, and read corporate mailboxes. One forgotten test account without MFA was enough.
- In the logs: failed sign-ins for many different users with the same (wrong) password pattern, from one source or a small set of sources, a few attempts per user; in Microsoft Entra ID, a burst of error AADSTS50126 (invalid user name or password) across many accounts. On domain controllers: event 4771 (Kerberos) or 4776 (NTLM) failures spread across many accounts; 4625 on the servers that were targeted.
- Prevent: MFA on every account, including test, service and "temporary" accounts; block legacy authentication protocols that cannot do MFA; banned-password lists (Entra Password Protection, also for on-premises AD); smart lockout, which locks out the attacker's attempts rather than the user.
- Detect: correlate failures across accounts, not per account. Entra ID Protection raises a password spray risk detection; a SIEM rule can do the same on any log.
Credential stuffing and brute force
Credential stuffing (see why passwords fail) tries user name and password pairs leaked from other sites; it works because people reuse passwords. Classic brute force (password guessing, T1110.001) hammers one account with many passwords and is the easiest to spot: many failures for one user, often ending in a lockout. Both lose most of their power against MFA and against checking new passwords against lists of breached ones.
Telling spraying from brute force
The difference is the shape of the failures: brute force is many attempts on one account; spraying is a few attempts on many accounts. This sketch groups failed sign-ins per source address and classifies each source:
from collections import defaultdict
# Failed sign-ins: (time, source IP, user). A few minutes from one sign-in log.
FAILED = [
("09:01", "203.0.113.45", "amara.okafor"),
("09:01", "203.0.113.45", "mei.chen"),
("09:02", "203.0.113.45", "hamid.rahimi"),
("09:02", "203.0.113.45", "sanne.devries"),
("09:03", "203.0.113.45", "joost.bakker"),
("09:03", "203.0.113.45", "femke.jansen"),
("09:04", "198.51.100.7", "ravi.kumar"),
("09:04", "198.51.100.7", "ravi.kumar"),
("09:05", "198.51.100.7", "ravi.kumar"),
("09:05", "198.51.100.7", "ravi.kumar"),
("09:05", "198.51.100.7", "ravi.kumar"),
("09:06", "198.51.100.7", "ravi.kumar"),
("09:07", "192.0.2.20", "lucia.romero"),
]
def classify(failed, min_users=5, min_attempts=5):
per_source = defaultdict(list)
for _time, source, user in failed:
per_source[source].append(user)
for source in sorted(per_source):
users = per_source[source]
distinct = len(set(users))
per_user = len(users) / distinct
if distinct >= min_users and per_user <= 2:
verdict = "possible password spraying"
elif distinct == 1 and len(users) >= min_attempts:
verdict = "possible brute force on one account"
else:
verdict = "normal noise"
print(f"{source:<14} failures={len(users):<3} users={distinct:<3} {verdict}")
classify(FAILED)
192.0.2.20 failures=1 users=1 normal noise 198.51.100.7 failures=6 users=1 possible brute force on one account 203.0.113.45 failures=6 users=6 possible password spraying
Real attackers make this harder: they rotate through thousands of proxy addresses and spread attempts over days, as in the Midnight Blizzard case. Production rules therefore also group by time window across all sources ("how many distinct accounts failed with the same error in the last hour?") and by password hash where the identity provider exposes it, and they use the identity provider's own risk detections.
Attacks on MFA and tokens
Once MFA is common, attackers aim at the MFA step itself or skip it by stealing what the identity provider hands out after a successful sign-in.
MFA fatigue
With a stolen password, the attacker triggers push notification after push notification until the user approves one, often combined with a call or chat message from "IT" (T1621). Uber's 2022 breach, which Uber attributed to the Lapsus$ group, was reported to have worked this way. The mechanism and the user's side are on Passwords and Authentication and MFA and Passwordless.
- In the logs: many MFA prompts denied or timed out for one user, then one approval, often at an odd hour or from a new location.
- Prevent: number matching and additional context in the prompt; better, phishing-resistant MFA, which has no prompt to approve blindly.
- Detect and respond: alert on repeated denials; let users report a suspicious prompt with one tap, and treat that report as a compromised password.
Adversary-in-the-middle phishing
In adversary-in-the-middle phishing (AiTM, T1557), the phishing link leads to a proxy server that sits between the victim and the real sign-in page. The victim sees the real page, with the real company branding, and completes a real MFA challenge — code, push or number matching — because the proxy passes everything through. The proxy keeps a copy of the session cookie the identity provider returns at the end. MFA worked; the attacker still got in.
Phishing-resistant methods stop this. A passkey or FIDO2 security key signs a challenge that includes the web origin it is talking to; on the proxy's domain the credential for the real domain is simply not offered (see MFA and Passwordless). Certificate-based authentication and Windows Hello for Business are phishing-resistant for the same reason: the proof is bound to something the proxy cannot replay.
Token theft
Token theft is stealing a session cookie, access token or refresh token that an identity provider issued after a successful sign-in, and replaying it from the attacker's own device. Tokens represent a sign-in that already happened, including its MFA, so whoever holds them is treated as signed in until they expire or are revoked. Tokens are stolen through AiTM phishing (T1539), through malware that copies browser cookies, and through OAuth tricks (T1528): consent phishing (getting a user to grant a malicious app access) and device code phishing. In the latter, the victim is lured to type an attacker's code on the real Microsoft device sign-in page; Microsoft reported a campaign of this kind by a group it tracks as Storm-2372 in February 2025.
- In the logs: a successful sign-in followed shortly by activity on the same session from a different IP address, country or autonomous system; a new inbox rule or MFA method registered right after; Entra ID Protection risk detections for anomalous tokens or attacker-in-the-middle activity.
- Prevent: phishing-resistant MFA (stops AiTM); Conditional Access that requires a compliant or hybrid-joined device, so a token replayed from an unmanaged machine is refused (see Conditional Access and Zero Trust); token protection, a Conditional Access session control that binds sign-in tokens to the device they were issued to, for supported applications and platforms; blocking the device code flow for users who do not need it; restricting which apps users may consent to.
- Respond: resetting the password is not enough, because existing tokens stay valid. Revoke the user's sessions and refresh tokens as well (shown below), and review registered MFA methods, inbox rules and app consents.
# Microsoft Graph PowerShell: invalidate all refresh tokens and session cookies of a user
Connect-MgGraph -Scopes "User.RevokeSessions.All"
Revoke-MgUserSignInSession -UserId "sanne.devries@example.com"
Continuous access evaluation shortens the gap after revocation for applications that support it: they learn about the revocation within minutes instead of waiting for the access token to expire.
Reusing hashes and tickets in Active Directory
When a user or admin signs in to a Windows machine, the Local Security Authority Subsystem Service (LSASS) keeps credential material in memory so that single sign-on to file shares and other servers works: NTLM hashes and Kerberos tickets. An attacker with local administrator rights on that machine can read that memory (LSASS memory dumping, T1003.001). They do not need the password itself.
Pass-the-hash
In pass-the-hash (T1550.002), the attacker authenticates with NTLM using a stolen password hash instead of the password. NTLM only proves knowledge of the hash, so the hash is the credential. A classic amplifier was the same local Administrator password on every workstation: one hash opened all of them.
Pass-the-ticket
In pass-the-ticket (T1550.003), the attacker copies a Kerberos ticket-granting ticket or service ticket from memory and injects it into their own session. Until the ticket expires, they act as that user — no password, no hash, no MFA prompt.
Defending against credential reuse
- Tiering. Domain admins never sign in to workstations or ordinary servers, so their hashes and tickets are never there to steal (see Privileged Access Management). This is the most important single control.
- Windows LAPS. A unique, rotated local Administrator password per machine, so one stolen hash opens one machine.
- Protected Users group. Members cannot use NTLM, cannot use DES or RC4 in Kerberos preauthentication, and receive TGTs limited to 4 hours (see Users, Groups and Computers).
- Credential Guard. Isolates secrets from LSASS with virtualization-based security, so memory dumping yields far less.
- Less NTLM. Audit NTLM use and move applications to Kerberos; Microsoft has deprecated all NTLM versions and removed NTLMv1 from Windows 11 24H2 and Windows Server 2025.
- No local admin for users, and endpoint detection and response (EDR) that alerts on access to LSASS memory.
In the logs: NTLM logons (event 4624 with authentication package NTLM, and 4776 on domain controllers) between workstations, or for admin accounts where Kerberos is expected; one account authenticating to many machines in a short time; tickets used from a different address than the one they were issued to. Products such as Microsoft Defender for Identity watch domain controller traffic for exactly these patterns.
Attacks on Kerberos
Kerberoasting
Any authenticated domain user may ask for a service ticket for any service principal name (SPN); that is how Kerberos is designed. Part of the ticket is encrypted with a key derived from the service account's password. In Kerberoasting (T1558.003), an attacker with any domain account requests tickets for user accounts that have SPNs and then tries to crack the password offline, on their own hardware, where no lockout applies. Service accounts with short, human-chosen passwords that never change — and often high privileges — are the target. Tickets encrypted with RC4 are much faster to crack than AES ones.
- Prevent: use group Managed Service Accounts (gMSA) or, on Windows Server 2025, delegated Managed Service Accounts (dMSA), whose passwords are long, random and rotated automatically; otherwise give service accounts long random passwords (25+ characters) from a vault; remove SPNs that are no longer used; allow only AES. Since Microsoft's RC4 changes for CVE-2026-20833 (enforced from April 2026, permanent from July 2026), domain controllers issue AES-only service tickets unless RC4 is explicitly configured per account.
- Detect: event 4769 (service ticket requested) with ticket encryption type 0x17 (RC4) where AES is the norm; one account requesting tickets for many different SPNs in a short time; a "honey" account with an SPN that no real system uses, so any ticket request for it is suspicious.
A defensive inventory of the accounts at risk is a normal admin task (not run here; output illustrative):
# User accounts with an SPN (Kerberoastable), with password age
Get-ADUser -Filter 'servicePrincipalName -like "*"' -Properties servicePrincipalName, PasswordLastSet |
Select-Object SamAccountName, PasswordLastSet
# Accounts that do not require Kerberos preauthentication (AS-REP roastable)
Get-ADUser -Filter 'DoesNotRequirePreAuth -eq $true' | Select-Object SamAccountName
SamAccountName PasswordLastSet -------------- --------------- svc-sql-billing 3/14/2017 10:22:41 AM svc-backup 6/2/2019 4:05:13 PM SamAccountName -------------- legacy-scanner
A service account password from 2017 is exactly what Kerberoasting finds. Converting it to a gMSA or dMSA, or at least resetting it to a long random value, removes the risk.
AS-REP roasting
Kerberos preauthentication makes the client prove it knows the password (by encrypting a timestamp) before the key distribution center answers. Some accounts have it turned off ("Do not require Kerberos preauthentication"), usually for an old application. In AS-REP roasting (T1558.004), anyone can ask the domain controller for such an account's authentication reply (AS-REP), part of which is encrypted with the user's password key, and crack it offline — without even having a domain account.
- Prevent: require preauthentication on every account (find exceptions with the query above) and give any remaining exception a long random password.
- Detect: event 4768 (TGT requested) with pre-authentication type 0, for accounts that should never appear that way.
Golden ticket
Every ticket-granting ticket in a domain is encrypted and signed
with the key of one account: krbtgt, the KDC service
account. A
golden ticket (T1558.001) is a
TGT the attacker forges with a stolen KRBTGT key. Domain controllers
accept it because it is signed correctly, and it can name any user,
any group membership and any lifetime. The attacker must already
have domain-level control to get the key (usually through DCSync),
so a golden ticket is about keeping access: it survives
password resets of every normal account. A silver ticket (T1558.002)
is the smaller version: a service ticket forged with one service
account's key, valid only for that service.
- Prevent: protect tier 0 — domain controllers, their backups, and every account and system that can control them — so the key is never stolen.
- Respond: after a domain compromise, reset the KRBTGT password twice. Domain controllers accept tickets signed with the current and the previous key, so one reset leaves forged tickets valid. Leave enough time between the two resets for replication to finish and for legitimate tickets to expire (at least the maximum ticket lifetime, 10 hours by default); resetting twice in quick succession breaks authentication across the domain.
- Detect: ticket lifetimes longer than policy allows, service ticket requests (4769) with no matching TGT request (4768) on any domain controller, and accounts in tickets that do not exist. In practice this needs a tool that correlates across all domain controllers.
- Silver tickets: prevent with gMSA/dMSA and AES for service accounts; detect service tickets used without a matching 4769 on any domain controller (this needs a tool such as Microsoft Defender for Identity).
DCSync
Domain controllers copy changes to each other through directory replication, including password hashes. In DCSync (T1003.006), an attacker with an account that holds the replication rights — "Replicating Directory Changes" and "Replicating Directory Changes All" on the domain — pretends to be a domain controller and asks a real one to replicate secrets: every user's hash, including KRBTGT's. Nothing needs to run on the domain controller itself.
- Prevent: by default only domain controllers and the highest admin groups have those rights. Audit regularly who holds them on the domain object; synchronization tools may legitimately need them: Microsoft Entra Connect's AD DS connector account needs both for password hash synchronization, which makes it tier 0.
-
Detect: replication requests from an address that
is not a domain controller. With directory service access auditing
configured on the domain object, event 4662 records the operation;
the properties contain the rights' GUIDs, for example
1131f6ad-9c07-11d1-f79f-00c04fc2dcd2for Replicating Directory Changes All. An alert on those GUIDs for any account that is not a domain controller is a high-value rule.
Defense checklist
- MFA on every human account, without exceptions, and phishing-resistant MFA for admins and high-risk users first. Block legacy authentication.
- Remove forgotten accounts: test tenants, old service accounts, leavers (see Identity Lifecycle).
- Banned-password lists and long passwords, no forced periodic changes, smart lockout.
- Tier your admins and use privileged access workstations and just-in-time elevation (see Privileged Access Management).
- Windows LAPS on every machine; no local admin rights for users.
- Managed service accounts (gMSA, dMSA) or long random passwords; AES only; preauthentication required everywhere.
- Protected Users for admin accounts; reduce NTLM.
- Watch replication rights and everything else in tier 0; know how and when to reset KRBTGT.
- Device-based Conditional Access and token protection; restrict app consent and the device code flow.
- Collect and watch the logs: Entra sign-in and audit logs, domain controller security events, in a SIEM with rules for the patterns above (see Monitoring and Troubleshooting Identity).
When an identity is compromised, follow the incident process (see Incident Response): contain first (disable the account, revoke sessions), then find out what the attacker did with it in the audit logs before you declare it clean.