<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: detecting-token-theft-and-replay
description: >-
  Detect theft and replay of OAuth access tokens, refresh tokens, session
  cookies, and Kerberos tickets. Covers token binding validation, session
  anomaly detection, continuous access evaluation, and incident response
  for compromised tokens across Azure AD, Okta, and AWS.
domain: cybersecurity
subdomain: identity-access-management
tags:
  - token-theft
  - token-replay
  - session-hijacking
  - oauth
  - cookie-theft
  - continuous-access-evaluation
  - azure-ad
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1528", "T1550.001"]
---

# Detecting Token Theft and Replay

## Overview

Token theft allows attackers to impersonate users without credentials. Stolen
OAuth tokens, session cookies, or Kerberos tickets bypass MFA entirely — the
authentication already happened. AiTM (Adversary-in-the-Middle) phishing kits
harvest session cookies in real time, making token theft the dominant post-MFA
attack pattern. Detection requires correlating token usage with device, network,
and behavioral context.

Mode: `[MODE: BLUE]` for detection; `[MODE: RED]` for token theft simulation.

MITRE ATT&CK: T1528 (Steal Application Access Token), T1539 (Steal Web Session Cookie), T1550.001 (Application Access Token)

## Prerequisites

- Azure AD P2 (Identity Protection, CAE)
- Microsoft Defender for Cloud Apps (session control)
- SIEM with Azure AD sign-in and audit log ingestion
- Okta System Log access
- Python 3.10+ for agent tooling

## Key Concepts

### Token Theft Vectors

| Vector | Token Type | Detection Difficulty |
|--------|-----------|---------------------|
| AiTM Phishing | Session cookie | Medium |
| Pass-the-Cookie | Browser session cookie | Medium |
| Infostealer Malware | All browser tokens | Hard |
| Device Code Phishing | OAuth refresh token | Medium |
| Token Cache Extraction | MSAL/ADAL cached tokens | Hard |
| Man-in-the-Browser | Session cookie | Hard |

### Azure AD Token Theft Detection (KQL)

```kql
// Detect token replay — same token used from different IPs
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| project TimeGenerated, UserPrincipalName, IPAddress,
    UniqueTokenIdentifier, DeviceDetail, Location
| summarize IPs=make_set(IPAddress), Count=count()
    by UniqueTokenIdentifier, UserPrincipalName
| where array_length(IPs) > 1
| project UserPrincipalName, UniqueTokenIdentifier, IPs, Count

// Detect AiTM phishing — session cookie replay indicators
SigninLogs
| where TimeGenerated > ago(1h)
| where ResultType == 0
| where RiskEventTypes_v2 has "anomalousToken"
    or RiskEventTypes_v2 has "tokenIssuerAnomaly"
| project TimeGenerated, UserPrincipalName, IPAddress,
    RiskLevelDuringSignIn, RiskEventTypes_v2,
    DeviceDetail, Location, AuthenticationProcessingDetails

// Token used from non-compliant device after compliant sign-in
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| project TimeGenerated, UserPrincipalName, IPAddress,
    DeviceDetail.isCompliant, DeviceDetail.deviceId,
    ConditionalAccessStatus
| where DeviceDetail_isCompliant == false
| join kind=inner (
    SigninLogs
    | where DeviceDetail_isCompliant == true
    | distinct UserPrincipalName
) on UserPrincipalName
```

### Continuous Access Evaluation (CAE)

```powershell
# Check CAE status on Conditional Access policies
Connect-MgGraph -Scopes "Policy.Read.All"

Get-MgIdentityConditionalAccessPolicy |
  Select-Object DisplayName, State,
    @{N="CAE"; E={$_.SessionControls.ContinuousAccessEvaluation.Mode}}

# Enable CAE — strict enforcement
$policy = @{
    SessionControls = @{
        ContinuousAccessEvaluation = @{
            Mode = "strictEnforcement"
        }
    }
}
Update-MgIdentityConditionalAccessPolicy `
    -ConditionalAccessPolicyId "POLICY_ID" `
    -BodyParameter $policy
```

### Okta Session Anomaly Detection

```bash
# Query suspicious session events
curl -s -H "Authorization: SSWS ${OKTA_API_TOKEN}" \
  "https://${OKTA_DOMAIN}/api/v1/logs?\
filter=eventType+eq+%22user.session.impersonation%22\
+or+eventType+eq+%22policy.evaluate_sign_on%22&\
since=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ)" | \
  jq '[.[] | {eventType: .eventType, actor: .actor.alternateId,
    ip: .client.ipAddress, outcome: .outcome.result}]'
```

### Sigma Detection Rule

```yaml
title: Potential Token Replay — Multi-IP Token Usage
id: 8b4d2e71-5f3a-4c9d-a1b6-7e8f9d2c3a5b
status: experimental
description: >-
  Detects a single authentication token being used from multiple
  IP addresses, indicating possible token theft and replay.
logsource:
  category: authentication
  product: azure
detection:
  selection:
    ResultType: 0
  condition: selection | count(IPAddress) by UniqueTokenIdentifier > 1
  timeframe: 1h
falsepositives:
  - VPN or proxy IP changes during active session
  - Mobile users switching between Wi-Fi and cellular
level: high
tags:
  - attack.credential_access
  - attack.t1528
  - attack.t1539
```

## Workflow

1. **Detect** — Alert on anomalousToken risk detection in Azure AD
2. **Validate** — Confirm token used from unexpected IP/device/location
3. **Contain** — Revoke all refresh tokens for affected user immediately
4. **Investigate** — Trace mailbox rules, app consent, data access during session
5. **Remediate** — Force re-authentication, enable CAE strict enforcement
6. **Harden** — Deploy token binding, compliant device requirement

### Token Revocation

```bash
# Azure AD — revoke all user sessions
curl -s -X POST -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  "https://graph.microsoft.com/v1.0/users/USER_ID/revokeSignInSessions"

# Okta — clear user sessions
curl -s -X DELETE -H "Authorization: SSWS ${OKTA_API_TOKEN}" \
  "https://${OKTA_DOMAIN}/api/v1/users/USER_ID/sessions"
```

## Verification

- [ ] Continuous Access Evaluation enabled in strict enforcement mode
- [ ] Conditional Access requires compliant/hybrid joined device for token binding
- [ ] Azure AD Identity Protection anomalousToken risk detection enabled
- [ ] Token lifetime policies enforce short access token life (< 1 hour)
- [ ] Sign-in risk policy triggers MFA on medium+ risk sign-ins
- [ ] Refresh token revocation tested and documented in IR playbook
- [ ] SIEM correlation rule for multi-IP token usage deployed
- [ ] AiTM phishing indicators monitored (unfamiliar sign-in properties)

## References

- [Microsoft — Token Theft Playbook](https://learn.microsoft.com/en-us/security/operations/token-theft-playbook)
- [Microsoft — Continuous Access Evaluation](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation)
- [MITRE ATT&CK T1528](https://attack.mitre.org/techniques/T1528/)
- [MITRE ATT&CK T1539](https://attack.mitre.org/techniques/T1539/)
