agentsclimarketplace

Hunting saas sso token abuse

Skill adriannoes/awesome-agentic-ai/cursor-claude-codex/skills/anthropic-cybersecurity-skills/skills/hunting-saas-sso-token-abuse

329 agent skills (Cursor, Claude Code & Codex), 5,380 OpenClaw skills, 201 ML notebooks, 7 textbooks, 52 research papers, 17 industry reports for PMs, Designers & Developers.

Install
npx -y skills add adriannoes/awesome-agentic-ai --skill hunting-saas-sso-token-abuse

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Detect SSO and OAuth token replay and SaaS lateral movement.

The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

10.9 KB, as published. Nobody here has run it

Hunting SaaS SSO Token Abuse

Overview

Adversaries increasingly bypass MFA not by defeating it but by stealing the artifacts issued after a successful authentication — session cookies, OAuth access/refresh tokens, and Primary Refresh Tokens (PRTs). With a stolen token an attacker replays the existing session ("pass-the-cookie" / token replay), inheriting the victim's authenticated state across federated SaaS without ever prompting for credentials or MFA. Mandiant's M-Trends reporting and Microsoft/Okta incident data both highlight token theft as a dominant cloud lateral-movement technique, mapped to MITRE ATT&CK T1550.001 Use Alternate Authentication Material: Application Access Token.

Detection relies on correlating identity telemetry rather than watching for failed logins. In Microsoft Entra ID the key tables are SigninLogs (interactive), AADNonInteractiveUserSignInLogs (where replayed cookies/refresh tokens commonly surface), and AADServicePrincipalSignInLogs. Entra now exposes linkable identifiersSessionId and UniqueTokenIdentifier — that let a hunter stitch every artifact derived from one root authentication event together and spot a single session being used from multiple IPs, ASNs, or device fingerprints. In Okta the System Log carries authentication.sso, policy.evaluate_sign_on, and user.session.start events with a deviceToken/session context; the same session token appearing from divergent IPs/user-agents is the tell. Okta Identity Threat Protection (ITP) can natively flag "suspected session hijacking."

This skill provides a hypothesis-driven hunt: baseline normal session behavior, then look for impossible travel within a single session, refresh-token reuse, token use from anomalous infrastructure (hosting/VPS ASNs), and SaaS access patterns inconsistent with the user's device. Source: MITRE ATT&CK T1550.001; Microsoft Entra ID sign-in log documentation; Okta System Log reference; Mandiant M-Trends.

When to Use

  • Threat hunting for MFA-bypass via stolen tokens/cookies across Entra ID and SaaS
  • Investigating an alert for impossible travel, anomalous OAuth grant, or token reuse
  • Validating detection coverage for T1550.001 after a phishing/AiTM incident
  • Building Sentinel/Splunk/Okta detections for session-token replay
  • Post-incident hunting to scope SaaS lateral movement from a compromised identity

Prerequisites

  • Entra ID sign-in logs flowing to a queryable store (Microsoft Sentinel / Log Analytics):
    # Confirm the diagnostic settings export SigninLogs + non-interactive logs to a workspace
    az monitor diagnostic-settings list --resource \
      /providers/Microsoft.aadiam/diagnosticSettings -o table
    
  • Okta System Log access via API or SIEM ingestion:
    curl -s -H "Authorization: SSWS $OKTA_API_TOKEN" \
      "https://<org>.okta.com/api/v1/logs?filter=eventType eq \"user.session.start\"&since=2026-06-01T00:00:00Z"
    
  • An IP enrichment source (GeoIP + ASN/hosting-provider classification)
  • Read access to the SIEM (KQL for Sentinel, SPL for Splunk)
  • Python 3.9+ for the helper script (requests for the Okta API)

Objectives

  • Baseline normal per-user session behavior (IPs, ASNs, devices, SaaS apps)
  • Correlate Entra sign-in artifacts by SessionId / UniqueTokenIdentifier
  • Detect a single session used from multiple IPs/ASNs (token replay)
  • Detect impossible travel within one authenticated session
  • Detect refresh-token reuse and anomalous OAuth grants
  • Hunt Okta System Log for reused session tokens across contexts
  • Produce findings and feed confirmed patterns into standing detections

MITRE ATT&CK Mapping

IDNameUse in this skill
T1550.001Use Alternate Authentication Material: Application Access TokenCore technique — replaying stolen OAuth tokens/cookies
T1539Steal Web Session CookieThe cookie theft that precedes pass-the-cookie replay
T1528Steal Application Access TokenAcquisition of OAuth tokens via phishing/illicit consent
T1078.004Valid Accounts: Cloud AccountsReplayed tokens grant valid-account access to SaaS
T1098.001Account Manipulation: Additional Cloud CredentialsFollow-on persistence after token abuse

Workflow

1. Correlate Entra sign-in artifacts by session

Stitch interactive, non-interactive, and SP sign-ins for one session to see the full chain.

union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(7d)
| where isnotempty(SessionId)
| summarize IPs=make_set(IPAddress), Apps=make_set(AppDisplayName),
            Locations=make_set(tostring(LocationDetails.countryOrRegion)),
            Count=count() by SessionId, UserPrincipalName
| where array_length(IPs) > 1

2. Detect a single session used from multiple ASNs (token replay)

AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(24h)
| extend ASN = tostring(parse_json(tostring(NetworkLocationDetails))[0].networkType)
| summarize distinctIPs = dcount(IPAddress),
            ipset = make_set(IPAddress) by SessionId, UserPrincipalName
| where distinctIPs >= 2

3. Detect impossible travel within one authenticated session

SigninLogs
| where TimeGenerated > ago(7d)
| project TimeGenerated, UserPrincipalName, IPAddress,
          City=tostring(LocationDetails.city),
          Country=tostring(LocationDetails.countryOrRegion), SessionId
| order by UserPrincipalName, TimeGenerated asc
| serialize
| extend prevCountry = prev(Country), prevTime = prev(TimeGenerated),
         prevUser = prev(UserPrincipalName)
| where UserPrincipalName == prevUser and Country != prevCountry
        and datetime_diff('minute', TimeGenerated, prevTime) < 60

4. Detect token use from hosting/VPS infrastructure

Replayed tokens are frequently used from datacenter ASNs, unlike the user's residential/corporate ranges.

AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| extend asnOrg = tostring(parse_json(tostring(AutonomousSystemNumber)))
| where IPAddress in (toscalar(externaldata(ip:string)["<hosting-asn-iplist>"]))
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress

5. Hunt anomalous OAuth grants / illicit consent (token theft precursor)

AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName in ("Consent to application", "Add OAuth2PermissionGrant",
                          "Add delegated permission grant")
| extend app = tostring(TargetResources[0].displayName)
| project TimeGenerated, InitiatedBy, app, Result

6. Hunt the Okta System Log for reused session tokens

A single Okta session (deviceToken) used from divergent IPs/clients indicates hijack.

curl -s -H "Authorization: SSWS $OKTA_API_TOKEN" \
  "https://<org>.okta.com/api/v1/logs?filter=eventType eq \"policy.evaluate_sign_on\"&since=2026-06-15T00:00:00Z" \
  | jq -r '.[] | [.authenticationContext.externalSessionId, .client.ipAddress, .client.userAgent.rawUserAgent] | @tsv' \
  | sort | uniq -c | sort -rn

7. Splunk equivalent for Okta session reuse

index=okta eventType="policy.evaluate_sign_on"
| stats dc(client.ipAddress) as ip_count
        values(client.ipAddress) as ips
        values(client.userAgent.rawUserAgent) as agents
        by authenticationContext.externalSessionId actor.alternateId
| where ip_count > 1

8. Triage and respond

For confirmed token abuse, revoke sessions and rotate, then promote the hunt to a rule.

# Revoke all refresh tokens / sessions for the user in Entra
az rest --method POST \
  --url "https://graph.microsoft.com/v1.0/users/<userId>/revokeSignInSessions"

See scripts/agent.py to pull Okta logs and flag reused session tokens automatically.

Tools and Resources

ResourcePurposeLink
MITRE ATT&CK T1550.001Technique referencehttps://attack.mitre.org/techniques/T1550/001/
Entra sign-in logs schemaKQL hunting field referencehttps://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-azure-monitor-sign-ins-log-schema
Azure-Sentinel hunting repoCommunity KQL detectionshttps://github.com/Azure/Azure-Sentinel
Okta System Log APIEvent hunting sourcehttps://developer.okta.com/docs/reference/api/system-log/
Mandiant M-TrendsToken-theft threat landscapehttps://www.mandiant.com/m-trends
AzureAD-Attack-DefensePRT/token replay detection guidancehttps://github.com/Cloud-Architekt/AzureAD-Attack-Defense

Preventive Controls to Recommend

Detection should pair with controls that make stolen tokens far less useful:

  • Entra Conditional Access "token protection" binds the sign-in session to the device, so an exfiltrated cookie/PRT cannot be replayed off-device.
  • Continuous Access Evaluation (CAE) revokes access in near-real-time on risk events instead of waiting for token expiry.
  • Phishing-resistant MFA (FIDO2/passkeys) blocks the AiTM proxy phishing that harvests tokens in the first place.
  • Short token lifetimes + refresh-token rotation shrink the replay window and turn refresh-token reuse into an unambiguous compromise signal.
  • Okta Identity Threat Protection (ITP) flags suspected session hijacking natively.

False-Positive Tuning

Benign causeTuning
Corporate VPN/proxy egress (many users, few IPs)Allowlist known egress IPs/ASNs
Mobile carrier IP rotationWiden impossible-travel time/distance thresholds
Legitimate multi-device usersCorrelate device IDs, not just IPs
Backend/API calls within one sessionExclude expected service principals

Key Indicators

IndicatorSignal
One SessionId across multiple IPs/ASNsToken/cookie replay
Non-interactive sign-in from new datacenter IPReplayed refresh token
Impossible travel within < 1hConcurrent session use
Refresh-token reuse after rotationStrong compromise signal
New OAuth consent to unfamiliar appIllicit-consent token theft
Okta session token from divergent user-agentsSession hijack

Validation Criteria

  • Entra SigninLogs and AADNonInteractiveUserSignInLogs queryable
  • Okta System Log accessible via API or SIEM
  • Per-session correlation by SessionId produces results
  • Multi-IP / multi-ASN single-session query implemented
  • Impossible-travel-within-session query implemented
  • Anomalous OAuth consent hunt implemented
  • Okta reused-session-token hunt implemented
  • Confirmed findings triaged and sessions revoked
  • Effective queries promoted to standing detection rules
  • False-positive baseline (VPN/proxy egress) documented

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.