Agent Foskett Academy • Lesson 102 • Hunting Playbook Series

Hunting Playbook: Credential Theft in Microsoft Defender XDR.

The password was correct.

The sign-in succeeded.

MFA may even have completed successfully.

But twenty minutes later, the same account was accessing mail, cloud apps and resources from activity that did not fit the user. Agent Foskett knew this was not a password problem anymore. It was a credential theft investigation.

Agent Foskett Academy lesson hunting credential theft in Microsoft Defender XDR
Lesson overview

Learn how to hunt for credential theft by reviewing sign-in telemetry, authentication patterns, risky users, IP addresses, token activity, mailbox access and related Microsoft Defender XDR evidence.

Review suspicious sign-in activity
Compare locations, IP addresses and devices
Identify credential theft indicators
Build a user compromise timeline
🎯 Hunting Playbook Series
Lesson 102 moves from learning KQL syntax to applying KQL during a real identity investigation. The goal is to determine whether a user account has been accessed by someone who should not have access.
Previous Playbook →

Why credential theft matters

Credential theft is dangerous because the attacker may appear to be the user. The account signs in, the password works and the activity may not immediately look like malware.
The attacker uses valid identityCredential theft allows attackers to access cloud services, mailboxes, files and applications using an account that already exists.
The first sign-in may look normalA stolen password or session token can produce successful authentication activity without triggering an obvious endpoint malware alert.
The investigation requires correlationDefenders need to compare sign-ins, locations, IP addresses, devices, mailbox activity, alerts and user behaviour before deciding whether the account is compromised.

The credential theft hunting workflow

Agent Foskett investigates credential theft by building a timeline around the user account and then expanding outward into identity, cloud and endpoint evidence.
1. Start with the userIdentify the account, time window and original signal that caused concern.
2. Review recent sign-insLook for successful and failed sign-ins, new IP addresses, unusual countries, unfamiliar devices and unexpected authentication methods.
3. Compare normal behaviourCheck whether the sign-in pattern matches the user or represents a new access pattern.
4. Look for token or session abuseInvestigate activity where the password was not the only factor, including sessions, refresh behaviour and cloud app access.
5. Pivot into related activityReview mailbox access, cloud app events, device activity, alerts and directory changes related to the same account.
6. Decide the responseDetermine whether to revoke sessions, reset credentials, require MFA re-registration, disable the account or escalate incident response.

Step 1 — Review recent sign-ins for the account

Start with a single account and build the recent sign-in timeline. This helps establish what happened before and after the suspicious activity.
step-1-review-user-sign-ins.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
let TimeFrame = 7d;
let UserAccount = "user@contoso.com";
IdentityLogonEvents
| where Timestamp > ago(TimeFrame)
| where AccountUpn =~ UserAccount
| project Timestamp,
          AccountUpn,
          ActionType,
          IPAddress,
          Location,
          DeviceName,
          FailureReason
| order by Timestamp desc

Step 2 — Summarise sign-ins by IP address and location

Credential theft often introduces new network locations. A summary view helps identify unfamiliar IP addresses and locations quickly.
step-2-summarise-locations.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
let TimeFrame = 14d;
let UserAccount = "user@contoso.com";
IdentityLogonEvents
| where Timestamp > ago(TimeFrame)
| where AccountUpn =~ UserAccount
| summarize SignInCount = count(),
            FirstSeen = min(Timestamp),
            LastSeen = max(Timestamp),
            Devices = make_set(DeviceName, 20),
            Outcomes = make_set(ActionType, 20)
      by AccountUpn,
         IPAddress,
         Location
| order by LastSeen desc

Step 3 — Look for successful sign-ins after repeated failures

A suspicious pattern is repeated failure followed by success, especially from the same IP address or location.
step-3-failures-before-success.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
let TimeFrame = 7d;
IdentityLogonEvents
| where Timestamp > ago(TimeFrame)
| summarize FailedSignIns = countif(ActionType has "Failed"),
            SuccessfulSignIns = countif(ActionType has "Success"),
            FirstSeen = min(Timestamp),
            LastSeen = max(Timestamp),
            Locations = make_set(Location, 20)
      by AccountUpn,
         IPAddress
| where FailedSignIns > 5 and SuccessfulSignIns > 0
| order by FailedSignIns desc

Step 4 — Identify accounts using many IP addresses

A compromised account may be accessed from multiple networks, VPN exits, attacker infrastructure or automation platforms.
step-4-many-ip-addresses.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
let TimeFrame = 7d;
IdentityLogonEvents
| where Timestamp > ago(TimeFrame)
| where ActionType has "Success"
| summarize UniqueIPs = dcount(IPAddress),
            IPAddresses = make_set(IPAddress, 50),
            Locations = make_set(Location, 50),
            FirstSeen = min(Timestamp),
            LastSeen = max(Timestamp)
      by AccountUpn
| where UniqueIPs >= 5
| order by UniqueIPs desc

Step 5 — Pivot into cloud application activity

If the credentials were used successfully, the attacker may have accessed cloud applications after signing in.
step-5-cloud-app-activity.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
let TimeFrame = 7d;
let UserAccount = "user@contoso.com";
CloudAppEvents
| where Timestamp > ago(TimeFrame)
| where AccountId =~ UserAccount or AccountDisplayName =~ UserAccount
| project Timestamp,
          AccountId,
          AccountDisplayName,
          Application,
          ActionType,
          IPAddress,
          DeviceType,
          RawEventData
| order by Timestamp desc

Step 6 — Check for related alerts and evidence

Identity alerts, cloud app alerts and Defender XDR evidence can help confirm whether suspicious activity is part of a broader compromise.
step-6-related-alert-evidence.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
let TimeFrame = 7d;
let UserAccount = "user@contoso.com";
AlertEvidence
| where Timestamp > ago(TimeFrame)
| where AccountUpn =~ UserAccount
   or AccountName =~ UserAccount
| project Timestamp,
          AlertId,
          Title,
          EntityType,
          AccountUpn,
          AccountName,
          DeviceName,
          RemoteIP,
          EvidenceDirection
| order by Timestamp desc

Step 7 — Build a credential theft timeline

The strongest investigation output is often a single timeline that shows sign-ins, cloud activity and alerts together.
step-7-credential-theft-timeline.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
let TimeFrame = 7d;
let UserAccount = "user@contoso.com";
let SignIns =
    IdentityLogonEvents
    | where Timestamp > ago(TimeFrame)
    | where AccountUpn =~ UserAccount
    | project Timestamp,
              Source = "IdentityLogonEvents",
              Event = ActionType,
              Detail = strcat(IPAddress, " | ", Location),
              Account = AccountUpn;
let CloudActivity =
    CloudAppEvents
    | where Timestamp > ago(TimeFrame)
    | where AccountId =~ UserAccount or AccountDisplayName =~ UserAccount
    | project Timestamp,
              Source = "CloudAppEvents",
              Event = ActionType,
              Detail = tostring(Application),
              Account = coalesce(AccountId, AccountDisplayName);
let Alerts =
    AlertEvidence
    | where Timestamp > ago(TimeFrame)
    | where AccountUpn =~ UserAccount or AccountName =~ UserAccount
    | project Timestamp,
              Source = "AlertEvidence",
              Event = Title,
              Detail = EntityType,
              Account = coalesce(AccountUpn, AccountName);
union SignIns, CloudActivity, Alerts
| order by Timestamp asc

Common false positives

Corporate VPNsVPN exit points can make a user appear to sign in from a location that does not match their physical location.
Mobile networksMobile carrier routing can produce unusual IP addresses or locations, especially when users move between regions.
Password managers and automationSome sign-in patterns may come from synchronisation tools, automation or password manager integrations.
Legitimate travelThe user may genuinely be travelling, especially if the locations are plausible and activity matches their normal behaviour.
Shared accountsShared or poorly managed accounts can create confusing sign-in patterns because multiple people may use the same identity.
Cloud service routingCloud apps and proxies may create access patterns that need context before being treated as malicious.

Evidence that increases suspicion

New IP address plus successful sign-inA new IP address by itself is not proof. A new IP with unusual timing and successful access deserves deeper investigation.
Failed attempts before successRepeated failures followed by success can indicate password guessing, password spray or stolen credentials being tested.
Unusual cloud app activityMailbox access, file downloads or admin portal access soon after a suspicious sign-in may indicate account misuse.
Multiple countries or networksRapid movement across unrelated locations can suggest attacker infrastructure, VPN hopping or session abuse.
Related alertsIdentity, cloud app or endpoint alerts tied to the same account increase confidence that the event is not benign.
User denies the activityIf the user does not recognise the sign-in or activity, treat the account as potentially compromised until proven otherwise.

Investigation checklist

Was the sign-in successful?A failed attempt may still matter, but successful authentication changes the response priority.
Is the IP address known?Compare the IP address with previous activity, corporate ranges, VPN services and user history.
Does the location fit the user?Review whether the user was expected to travel, work remotely or use a mobile provider from that region.
What happened after sign-in?Check cloud app activity, mailbox access, downloads, file sharing, admin actions and alert evidence.
Is MFA involved?Determine whether MFA was satisfied, bypassed, not required or unexpectedly changed.
What response is required?Consider password reset, session revocation, MFA re-registration, account disablement and incident escalation.

Related Agent Foskett Academy lessons

Hunting Playbook: Impossible TravelInvestigate suspicious sign-ins that appear to occur from unrealistic locations.
Investigating IdentityLogonEventsUnderstand the identity sign-in telemetry used in credential theft investigations.
Investigating IdentityInfoUse identity context to understand accounts, roles and user details.
Investigating CloudAppEventsReview what happened after the account accessed cloud applications.
Building Reusable Hunting QueriesReuse tested KQL patterns during identity investigations.
Using arg_max() in KQLFind the latest activity for each user, IP address or investigation entity.

Coming next

Lesson 103 — Hunting Playbook: Malicious Inbox RulesNext, Agent Foskett investigates how attackers create inbox rules after mailbox compromise to hide evidence, forward email or maintain access to sensitive conversations.
Why this mattersCredential theft often leads directly to mailbox compromise, OAuth abuse, lateral movement and data theft. The faster defenders build the timeline, the faster they can contain the account.

Final thought

Credential theft investigations are rarely solved by one event.
Agent Foskett mindsetDo not ask whether the password was correct. Ask whether the behaviour belongs to the user.
Hunting Playbook principleBuild the timeline first. The timeline shows whether identity activity, cloud activity and alerts belong to one story.
Develop IT. Protect IT.GEMXIT PTY LTD | GEMXIT UK LTD

Hunting Playbook Credential Theft in Microsoft Defender XDR

Agent Foskett Academy Lesson 102 teaches defenders how to hunt for credential theft using Microsoft Defender XDR, Microsoft Entra ID telemetry, sign-in behaviour, authentication events, cloud application activity and KQL investigation workflows.

Investigate credential theft with KQL and Microsoft Defender XDR

This lesson explains how to review suspicious sign-ins, compare IP addresses and locations, detect failed attempts before success, pivot into CloudAppEvents and build a credential theft investigation timeline.

Microsoft Entra ID credential theft investigation playbook

Defenders can use IdentityLogonEvents, CloudAppEvents, AlertEvidence, sign-in summaries, location analysis and Defender XDR correlation to investigate stolen credentials and compromised accounts.