[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AEXYHYREYZ2WE9QHTJP2PJ":3,"skill-same:01M6AEXYHYREYZ2WE9QHTJP2PJ":103},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":61,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":65,"ownerDescription":66,"updatedAt":67,"install":68,"resources":81},"01M6AEXYHYREYZ2WE9QHTJP2PJ","hunting-saas-sso-token-abuse",null,"Hunts for stolen-session and OAuth\u002FPRT token replay (T1550.001) by correlating Microsoft Entra ID SigninLogs SessionId\u002FUniqueTokenIdentifier fields and Okta System Log sso\u002Fsession events to spot impossible travel, refresh-token reuse, and token use from anomalous ASNs. Use when hunting MFA-bypass via stolen cookies\u002Ftokens, investigating impossible-travel alerts, or scoping SaaS lateral movement after phishing.","mukul975\u002FAnthropic-Cybersecurity-Skills","mukul975","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F42860185?v=4","01M6ADEQR8T5M4EEG6C67BQCWF","Mahipal","01M6ADJPMYWG1E5GM1FWBE3128",35990,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fhunting-saas-sso-token-abuse\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"hunting saas sso token abuse","saas","sso","detection-engineering","okta","pass-the-cookie","t1550","PRT","impossible-travel","mfa","cybersecurity","token-theft","entra-id","OAuth","soc","phishing","cookies","threat-hunting","entra id","microsoft","2026-11-10 10:12:30",false,"---\nname: hunting-saas-sso-token-abuse\ndescription: Hunts for stolen-session and OAuth\u002FPRT token replay (T1550.001) by correlating Microsoft Entra ID SigninLogs SessionId\u002FUniqueTokenIdentifier fields and Okta System Log sso\u002Fsession events to spot impossible travel, refresh-token reuse, and token use from anomalous ASNs. Use when hunting MFA-bypass via stolen cookies\u002Ftokens, investigating impossible-travel alerts, or scoping SaaS lateral movement after phishing.\ndomain: cybersecurity\nsubdomain: soc-operations\ntags:\n- threat-hunting\n- sso\n- oauth\n- token-theft\n- pass-the-cookie\n- entra-id\n- okta\n- detection-engineering\nversion: '1.0'\nauthor: mahipal\nlicense: Apache-2.0\nnist_csf:\n- DE.CM-01\nmitre_attack:\n- T1550.001\n---\n# Hunting SaaS SSO Token Abuse\n\n## Overview\n\nAdversaries increasingly bypass MFA not by defeating it but by stealing the artifacts issued *after* a successful authentication — session cookies, OAuth access\u002Frefresh tokens, and Primary Refresh Tokens (PRTs). With a stolen token an attacker replays the existing session (\"pass-the-cookie\" \u002F 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\u002FOkta 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**.\n\nDetection 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\u002Frefresh tokens commonly surface), and `AADServicePrincipalSignInLogs`. Entra now exposes *linkable identifiers* — `SessionId` 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`\u002Fsession context; the same session token appearing from divergent IPs\u002Fuser-agents is the tell. Okta Identity Threat Protection (ITP) can natively flag \"suspected session hijacking.\"\n\nThis 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\u002FVPS 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.\n\n## When to Use\n\n- Threat hunting for MFA-bypass via stolen tokens\u002Fcookies across Entra ID and SaaS\n- Investigating an alert for impossible travel, anomalous OAuth grant, or token reuse\n- Validating detection coverage for T1550.001 after a phishing\u002FAiTM incident\n- Building Sentinel\u002FSplunk\u002FOkta detections for session-token replay\n- Post-incident hunting to scope SaaS lateral movement from a compromised identity\n\n## Prerequisites\n\n- Entra ID sign-in logs flowing to a queryable store (Microsoft Sentinel \u002F Log Analytics):\n  ```bash\n  # Confirm the diagnostic settings export SigninLogs + non-interactive logs to a workspace\n  az monitor diagnostic-settings list --resource \\\n    \u002Fproviders\u002FMicrosoft.aadiam\u002FdiagnosticSettings -o table\n  ```\n- Okta System Log access via API or SIEM ingestion:\n  ```bash\n  curl -s -H \"Authorization: SSWS $OKTA_API_TOKEN\" \\\n    \"https:\u002F\u002F\u003Corg>.okta.com\u002Fapi\u002Fv1\u002Flogs?filter=eventType eq \\\"user.session.start\\\"&since=2026-06-01T00:00:00Z\"\n  ```\n- An IP enrichment source (GeoIP + ASN\u002Fhosting-provider classification)\n- Read access to the SIEM (KQL for Sentinel, SPL for Splunk)\n- Python 3.9+ for the helper script (`requests` for the Okta API)\n\n## Objectives\n\n- Baseline normal per-user session behavior (IPs, ASNs, devices, SaaS apps)\n- Correlate Entra sign-in artifacts by `SessionId` \u002F `UniqueTokenIdentifier`\n- Detect a single session used from multiple IPs\u002FASNs (token replay)\n- Detect impossible travel within one authenticated session\n- Detect refresh-token reuse and anomalous OAuth grants\n- Hunt Okta System Log for reused session tokens across contexts\n- Produce findings and feed confirmed patterns into standing detections\n\n## MITRE ATT&CK Mapping\n\n| ID | Name | Use in this skill |\n|----|------|-------------------|\n| T1550.001 | Use Alternate Authentication Material: Application Access Token | Core technique — replaying stolen OAuth tokens\u002Fcookies |\n| T1539 | Steal Web Session Cookie | The cookie theft that precedes pass-the-cookie replay |\n| T1528 | Steal Application Access Token | Acquisition of OAuth tokens via phishing\u002Fillicit consent |\n| T1078.004 | Valid Accounts: Cloud Accounts | Replayed tokens grant valid-account access to SaaS |\n| T1098.001 | Account Manipulation: Additional Cloud Credentials | Follow-on persistence after token abuse |\n\n## Workflow\n\n### 1. Correlate Entra sign-in artifacts by session\nStitch interactive, non-interactive, and SP sign-ins for one session to see the full chain.\n```kusto\nunion SigninLogs, AADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(7d)\n| where isnotempty(SessionId)\n| summarize IPs=make_set(IPAddress), Apps=make_set(AppDisplayName),\n            Locations=make_set(tostring(LocationDetails.countryOrRegion)),\n            Count=count() by SessionId, UserPrincipalName\n| where array_length(IPs) > 1\n```\n\n### 2. Detect a single session used from multiple ASNs (token replay)\n```kusto\nAADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(24h)\n| extend ASN = tostring(parse_json(tostring(NetworkLocationDetails))[0].networkType)\n| summarize distinctIPs = dcount(IPAddress),\n            ipset = make_set(IPAddress) by SessionId, UserPrincipalName\n| where distinctIPs >= 2\n```\n\n### 3. Detect impossible travel within one authenticated session\n```kusto\nSigninLogs\n| where TimeGenerated > ago(7d)\n| project TimeGenerated, UserPrincipalName, IPAddress,\n          City=tostring(LocationDetails.city),\n          Country=tostring(LocationDetails.countryOrRegion), SessionId\n| order by UserPrincipalName, TimeGenerated asc\n| serialize\n| extend prevCountry = prev(Country), prevTime = prev(TimeGenerated),\n         prevUser = prev(UserPrincipalName)\n| where UserPrincipalName == prevUser and Country != prevCountry\n        and datetime_diff('minute', TimeGenerated, prevTime) \u003C 60\n```\n\n### 4. Detect token use from hosting\u002FVPS infrastructure\nReplayed tokens are frequently used from datacenter ASNs, unlike the user's residential\u002Fcorporate ranges.\n```kusto\nAADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(24h)\n| where ResultType == 0\n| extend asnOrg = tostring(parse_json(tostring(AutonomousSystemNumber)))\n| where IPAddress in (toscalar(externaldata(ip:string)[\"\u003Chosting-asn-iplist>\"]))\n| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress\n```\n\n### 5. Hunt anomalous OAuth grants \u002F illicit consent (token theft precursor)\n```kusto\nAuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName in (\"Consent to application\", \"Add OAuth2PermissionGrant\",\n                          \"Add delegated permission grant\")\n| extend app = tostring(TargetResources[0].displayName)\n| project TimeGenerated, InitiatedBy, app, Result\n```\n\n### 6. Hunt the Okta System Log for reused session tokens\nA single Okta session (`deviceToken`) used from divergent IPs\u002Fclients indicates hijack.\n```bash\ncurl -s -H \"Authorization: SSWS $OKTA_API_TOKEN\" \\\n  \"https:\u002F\u002F\u003Corg>.okta.com\u002Fapi\u002Fv1\u002Flogs?filter=eventType eq \\\"policy.evaluate_sign_on\\\"&since=2026-06-15T00:00:00Z\" \\\n  | jq -r '.[] | [.authenticationContext.externalSessionId, .client.ipAddress, .client.userAgent.rawUserAgent] | @tsv' \\\n  | sort | uniq -c | sort -rn\n```\n\n### 7. Splunk equivalent for Okta session reuse\n```spl\nindex=okta eventType=\"policy.evaluate_sign_on\"\n| stats dc(client.ipAddress) as ip_count\n        values(client.ipAddress) as ips\n        values(client.userAgent.rawUserAgent) as agents\n        by authenticationContext.externalSessionId actor.alternateId\n| where ip_count > 1\n```\n\n### 8. Triage and respond\nFor confirmed token abuse, revoke sessions and rotate, then promote the hunt to a rule.\n```bash\n# Revoke all refresh tokens \u002F sessions for the user in Entra\naz rest --method POST \\\n  --url \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\u002Fusers\u002F\u003CuserId>\u002FrevokeSignInSessions\"\n```\nSee `scripts\u002Fagent.py` to pull Okta logs and flag reused session tokens automatically.\n\n## Tools and Resources\n\n| Resource | Purpose | Link |\n|----------|---------|------|\n| MITRE ATT&CK T1550.001 | Technique reference | https:\u002F\u002Fattack.mitre.org\u002Ftechniques\u002FT1550\u002F001\u002F |\n| Entra sign-in logs schema | KQL hunting field reference | https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fentra\u002Fidentity\u002Fmonitoring-health\u002Freference-azure-monitor-sign-ins-log-schema |\n| Azure-Sentinel hunting repo | Community KQL detections | https:\u002F\u002Fgithub.com\u002FAzure\u002FAzure-Sentinel |\n| Okta System Log API | Event hunting source | https:\u002F\u002Fdeveloper.okta.com\u002Fdocs\u002Freference\u002Fapi\u002Fsystem-log\u002F |\n| Mandiant M-Trends | Token-theft threat landscape | https:\u002F\u002Fwww.mandiant.com\u002Fm-trends |\n| AzureAD-Attack-Defense | PRT\u002Ftoken replay detection guidance | https:\u002F\u002Fgithub.com\u002FCloud-Architekt\u002FAzureAD-Attack-Defense |\n\n## Preventive Controls to Recommend\n\nDetection should pair with controls that make stolen tokens far less useful:\n\n- **Entra Conditional Access \"token protection\"** binds the sign-in session to the\n  device, so an exfiltrated cookie\u002FPRT cannot be replayed off-device.\n- **Continuous Access Evaluation (CAE)** revokes access in near-real-time on risk\n  events instead of waiting for token expiry.\n- **Phishing-resistant MFA (FIDO2\u002Fpasskeys)** blocks the AiTM proxy phishing that\n  harvests tokens in the first place.\n- **Short token lifetimes + refresh-token rotation** shrink the replay window and turn\n  refresh-token reuse into an unambiguous compromise signal.\n- **Okta Identity Threat Protection (ITP)** flags suspected session hijacking natively.\n\n## False-Positive Tuning\n\n| Benign cause | Tuning |\n|--------------|--------|\n| Corporate VPN\u002Fproxy egress (many users, few IPs) | Allowlist known egress IPs\u002FASNs |\n| Mobile carrier IP rotation | Widen impossible-travel time\u002Fdistance thresholds |\n| Legitimate multi-device users | Correlate device IDs, not just IPs |\n| Backend\u002FAPI calls within one session | Exclude expected service principals |\n\n## Key Indicators\n\n| Indicator | Signal |\n|-----------|--------|\n| One `SessionId` across multiple IPs\u002FASNs | Token\u002Fcookie replay |\n| Non-interactive sign-in from new datacenter IP | Replayed refresh token |\n| Impossible travel within \u003C 1h | Concurrent session use |\n| Refresh-token reuse after rotation | Strong compromise signal |\n| New OAuth consent to unfamiliar app | Illicit-consent token theft |\n| Okta session token from divergent user-agents | Session hijack |\n\n## Validation Criteria\n\n- [ ] Entra `SigninLogs` and `AADNonInteractiveUserSignInLogs` queryable\n- [ ] Okta System Log accessible via API or SIEM\n- [ ] Per-session correlation by `SessionId` produces results\n- [ ] Multi-IP \u002F multi-ASN single-session query implemented\n- [ ] Impossible-travel-within-session query implemented\n- [ ] Anomalous OAuth consent hunt implemented\n- [ ] Okta reused-session-token hunt implemented\n- [ ] Confirmed findings triaged and sessions revoked\n- [ ] Effective queries promoted to standing detection rules\n- [ ] False-positive baseline (VPN\u002Fproxy egress) documented\n","# Hunting SaaS SSO Token Abuse\n\n## Overview\n\nAdversaries increasingly bypass MFA not by defeating it but by stealing the artifacts issued *after* a successful authentication — session cookies, OAuth access\u002Frefresh tokens, and Primary Refresh Tokens (PRTs). With a stolen token an attacker replays the existing session (\"pass-the-cookie\" \u002F 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\u002FOkta 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**.\n\nDetection 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\u002Frefresh tokens commonly surface), and `AADServicePrincipalSignInLogs`. Entra now exposes *linkable identifiers* — `SessionId` 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`\u002Fsession context; the same session token appearing from divergent IPs\u002Fuser-agents is the tell. Okta Identity Threat Protection (ITP) can natively flag \"suspected session hijacking.\"\n\nThis 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\u002FVPS 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.\n\n## When to Use\n\n- Threat hunting for MFA-bypass via stolen tokens\u002Fcookies across Entra ID and SaaS\n- Investigating an alert for impossible travel, anomalous OAuth grant, or token reuse\n- Validating detection coverage for T1550.001 after a phishing\u002FAiTM incident\n- Building Sentinel\u002FSplunk\u002FOkta detections for session-token replay\n- Post-incident hunting to scope SaaS lateral movement from a compromised identity\n\n## Prerequisites\n\n- Entra ID sign-in logs flowing to a queryable store (Microsoft Sentinel \u002F Log Analytics):\n  ```bash\n  # Confirm the diagnostic settings export SigninLogs + non-interactive logs to a workspace\n  az monitor diagnostic-settings list --resource \\\n    \u002Fproviders\u002FMicrosoft.aadiam\u002FdiagnosticSettings -o table\n  ```\n- Okta System Log access via API or SIEM ingestion:\n  ```bash\n  curl -s -H \"Authorization: SSWS $OKTA_API_TOKEN\" \\\n    \"https:\u002F\u002F\u003Corg>.okta.com\u002Fapi\u002Fv1\u002Flogs?filter=eventType eq \\\"user.session.start\\\"&since=2026-06-01T00:00:00Z\"\n  ```\n- An IP enrichment source (GeoIP + ASN\u002Fhosting-provider classification)\n- Read access to the SIEM (KQL for Sentinel, SPL for Splunk)\n- Python 3.9+ for the helper script (`requests` for the Okta API)\n\n## Objectives\n\n- Baseline normal per-user session behavior (IPs, ASNs, devices, SaaS apps)\n- Correlate Entra sign-in artifacts by `SessionId` \u002F `UniqueTokenIdentifier`\n- Detect a single session used from multiple IPs\u002FASNs (token replay)\n- Detect impossible travel within one authenticated session\n- Detect refresh-token reuse and anomalous OAuth grants\n- Hunt Okta System Log for reused session tokens across contexts\n- Produce findings and feed confirmed patterns into standing detections\n\n## MITRE ATT&CK Mapping\n\n| ID | Name | Use in this skill |\n|----|------|-------------------|\n| T1550.001 | Use Alternate Authentication Material: Application Access Token | Core technique — replaying stolen OAuth tokens\u002Fcookies |\n| T1539 | Steal Web Session Cookie | The cookie theft that precedes pass-the-cookie replay |\n| T1528 | Steal Application Access Token | Acquisition of OAuth tokens via phishing\u002Fillicit consent |\n| T1078.004 | Valid Accounts: Cloud Accounts | Replayed tokens grant valid-account access to SaaS |\n| T1098.001 | Account Manipulation: Additional Cloud Credentials | Follow-on persistence after token abuse |\n\n## Workflow\n\n### 1. Correlate Entra sign-in artifacts by session\nStitch interactive, non-interactive, and SP sign-ins for one session to see the full chain.\n```kusto\nunion SigninLogs, AADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(7d)\n| where isnotempty(SessionId)\n| summarize IPs=make_set(IPAddress), Apps=make_set(AppDisplayName),\n            Locations=make_set(tostring(LocationDetails.countryOrRegion)),\n            Count=count() by SessionId, UserPrincipalName\n| where array_length(IPs) > 1\n```\n\n### 2. Detect a single session used from multiple ASNs (token replay)\n```kusto\nAADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(24h)\n| extend ASN = tostring(parse_json(tostring(NetworkLocationDetails))[0].networkType)\n| summarize distinctIPs = dcount(IPAddress),\n            ipset = make_set(IPAddress) by SessionId, UserPrincipalName\n| where distinctIPs >= 2\n```\n\n### 3. Detect impossible travel within one authenticated session\n```kusto\nSigninLogs\n| where TimeGenerated > ago(7d)\n| project TimeGenerated, UserPrincipalName, IPAddress,\n          City=tostring(LocationDetails.city),\n          Country=tostring(LocationDetails.countryOrRegion), SessionId\n| order by UserPrincipalName, TimeGenerated asc\n| serialize\n| extend prevCountry = prev(Country), prevTime = prev(TimeGenerated),\n         prevUser = prev(UserPrincipalName)\n| where UserPrincipalName == prevUser and Country != prevCountry\n        and datetime_diff('minute', TimeGenerated, prevTime) \u003C 60\n```\n\n### 4. Detect token use from hosting\u002FVPS infrastructure\nReplayed tokens are frequently used from datacenter ASNs, unlike the user's residential\u002Fcorporate ranges.\n```kusto\nAADNonInteractiveUserSignInLogs\n| where TimeGenerated > ago(24h)\n| where ResultType == 0\n| extend asnOrg = tostring(parse_json(tostring(AutonomousSystemNumber)))\n| where IPAddress in (toscalar(externaldata(ip:string)[\"\u003Chosting-asn-iplist>\"]))\n| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress\n```\n\n### 5. Hunt anomalous OAuth grants \u002F illicit consent (token theft precursor)\n```kusto\nAuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName in (\"Consent to application\", \"Add OAuth2PermissionGrant\",\n                          \"Add delegated permission grant\")\n| extend app = tostring(TargetResources[0].displayName)\n| project TimeGenerated, InitiatedBy, app, Result\n```\n\n### 6. Hunt the Okta System Log for reused session tokens\nA single Okta session (`deviceToken`) used from divergent IPs\u002Fclients indicates hijack.\n```bash\ncurl -s -H \"Authorization: SSWS $OKTA_API_TOKEN\" \\\n  \"https:\u002F\u002F\u003Corg>.okta.com\u002Fapi\u002Fv1\u002Flogs?filter=eventType eq \\\"policy.evaluate_sign_on\\\"&since=2026-06-15T00:00:00Z\" \\\n  | jq -r '.[] | [.authenticationContext.externalSessionId, .client.ipAddress, .client.userAgent.rawUserAgent] | @tsv' \\\n  | sort | uniq -c | sort -rn\n```\n\n### 7. Splunk equivalent for Okta session reuse\n```spl\nindex=okta eventType=\"policy.evaluate_sign_on\"\n| stats dc(client.ipAddress) as ip_count\n        values(client.ipAddress) as ips\n        values(client.userAgent.rawUserAgent) as agents\n        by authenticationContext.externalSessionId actor.alternateId\n| where ip_count > 1\n```\n\n### 8. Triage and respond\nFor confirmed token abuse, revoke sessions and rotate, then promote the hunt to a rule.\n```bash\n# Revoke all refresh tokens \u002F sessions for the user in Entra\naz rest --method POST \\\n  --url \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\u002Fusers\u002F\u003CuserId>\u002FrevokeSignInSessions\"\n```\nSee `scripts\u002Fagent.py` to pull Okta logs and flag reused session tokens automatically.\n\n## Tools and Resources\n\n| Resource | Purpose | Link |\n|----------|---------|------|\n| MITRE ATT&CK T1550.001 | Technique reference | https:\u002F\u002Fattack.mitre.org\u002Ftechniques\u002FT1550\u002F001\u002F |\n| Entra sign-in logs schema | KQL hunting field reference | https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fentra\u002Fidentity\u002Fmonitoring-health\u002Freference-azure-monitor-sign-ins-log-schema |\n| Azure-Sentinel hunting repo | Community KQL detections | https:\u002F\u002Fgithub.com\u002FAzure\u002FAzure-Sentinel |\n| Okta System Log API | Event hunting source | https:\u002F\u002Fdeveloper.okta.com\u002Fdocs\u002Freference\u002Fapi\u002Fsystem-log\u002F |\n| Mandiant M-Trends | Token-theft threat landscape | https:\u002F\u002Fwww.mandiant.com\u002Fm-trends |\n| AzureAD-Attack-Defense | PRT\u002Ftoken replay detection guidance | https:\u002F\u002Fgithub.com\u002FCloud-Architekt\u002FAzureAD-Attack-Defense |\n\n## Preventive Controls to Recommend\n\nDetection should pair with controls that make stolen tokens far less useful:\n\n- **Entra Conditional Access \"token protection\"** binds the sign-in session to the\n  device, so an exfiltrated cookie\u002FPRT cannot be replayed off-device.\n- **Continuous Access Evaluation (CAE)** revokes access in near-real-time on risk\n  events instead of waiting for token expiry.\n- **Phishing-resistant MFA (FIDO2\u002Fpasskeys)** blocks the AiTM proxy phishing that\n  harvests tokens in the first place.\n- **Short token lifetimes + refresh-token rotation** shrink the replay window and turn\n  refresh-token reuse into an unambiguous compromise signal.\n- **Okta Identity Threat Protection (ITP)** flags suspected session hijacking natively.\n\n## False-Positive Tuning\n\n| Benign cause | Tuning |\n|--------------|--------|\n| Corporate VPN\u002Fproxy egress (many users, few IPs) | Allowlist known egress IPs\u002FASNs |\n| Mobile carrier IP rotation | Widen impossible-travel time\u002Fdistance thresholds |\n| Legitimate multi-device users | Correlate device IDs, not just IPs |\n| Backend\u002FAPI calls within one session | Exclude expected service principals |\n\n## Key Indicators\n\n| Indicator | Signal |\n|-----------|--------|\n| One `SessionId` across multiple IPs\u002FASNs | Token\u002Fcookie replay |\n| Non-interactive sign-in from new datacenter IP | Replayed refresh token |\n| Impossible travel within \u003C 1h | Concurrent session use |\n| Refresh-token reuse after rotation | Strong compromise signal |\n| New OAuth consent to unfamiliar app | Illicit-consent token theft |\n| Okta session token from divergent user-agents | Session hijack |\n\n## Validation Criteria\n\n- [ ] Entra `SigninLogs` and `AADNonInteractiveUserSignInLogs` queryable\n- [ ] Okta System Log accessible via API or SIEM\n- [ ] Per-session correlation by `SessionId` produces results\n- [ ] Multi-IP \u002F multi-ASN single-session query implemented\n- [ ] Impossible-travel-within-session query implemented\n- [ ] Anomalous OAuth consent hunt implemented\n- [ ] Okta reused-session-token hunt implemented\n- [ ] Confirmed findings triaged and sessions revoked\n- [ ] Effective queries promoted to standing detection rules\n- [ ] False-positive baseline (VPN\u002Fproxy egress) documented\n",{"name":5,"tags":49,"author":51,"domain":34,"license":15,"version":52,"nist_csf":53,"subdomain":55,"description":7,"mitre_attack":56},[41,26,50,35,29,36,28,27],"oauth","mahipal","1.0",[54],"DE.CM-01","soc-operations",[57],"T1550.001","main","54a798831d2266a3ca61ce68a7acb80b81160d57","skills\u002Fhunting-saas-sso-token-abuse",4395,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills","https:\u002F\u002Fmahipal.engineer\u002FAnthropic-Cybersecurity-Skills\u002F","https:\u002F\u002Fgithub.com\u002Fmukul975","Mahipal.engineer","🔐 Cybersecurity | 💻 Dev | 📷 Street Photographer\r\n🎓 MSc | 📚 Research & AI Security","2026-08-31 12:32:44",{"source":8,"skillName":5,"commands":69,"prompt":79,"zipAvailable":80},[70,73,76],{"tool":71,"command":72},"npx","npx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill hunting-saas-sso-token-abuse",{"tool":74,"command":75},"bunx","bunx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill hunting-saas-sso-token-abuse",{"tool":77,"command":78},"pnpm","pnpm dlx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill hunting-saas-sso-token-abuse","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fhunting-saas-sso-token-abuse\u002FSKILL.md",true,[82,87,93,97],{"path":83,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"LICENSE","许可证",11255,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fhunting-saas-sso-token-abuse\u002FLICENSE",{"path":88,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":91,"sourceHtmlUrl":92},"references\u002Fapi-reference.md","REFERENCE","参考文档",2231,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fhunting-saas-sso-token-abuse\u002Freferences\u002Fapi-reference.md",{"path":94,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":95,"sourceHtmlUrl":96},"references\u002Fstandards.md",1423,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fhunting-saas-sso-token-abuse\u002Freferences\u002Fstandards.md",{"path":98,"resourceType":99,"resourceTypeDesc":100,"sizeBytes":101,"sourceHtmlUrl":102},"scripts\u002Fagent.py","SCRIPT","脚本",5280,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fhunting-saas-sso-token-abuse\u002Fscripts\u002Fagent.py",[104,131,155,183,209,236],{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":111,"publishedAt":44},"01M6AGDM3HJXTKXX15ZZ0ZVCJ3","verifying-build-provenance-with-slsa-sigstore","Verifies artifact signatures and SLSA provenance using Sigstore's cosign (verify, verify-attestation, verify-blob-attestation) and slsa-verifier (verify-artifact), enforcing keyless OIDC builder identity and source repo against SLSA Build levels. Use in CI\u002FCD before deploying artifacts, when consuming third-party attestations, establishing a SLSA Build L3 pipeline, or confirming provenance during incident response or admission control.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fverifying-build-provenance-with-slsa-sigstore\u002FSKILL.md",[110],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[112,113,114,115,116,34,117,118,119,120,121,122,123,124,125,126,127,128,129,130],"sigstore","provenance","slsa","verifying build provenance with slsa sigstore","security","incident response","identity","pr","code","artifacts","ci","supply-chain","pipeline","supply-chain-security","t1195","attestation","code-signing","cosign","keyless",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":138,"publishedAt":44},"01M6AGDGBPWYVZ2F11GFKJ4HZ9","validating-tpm-measured-boot-attestation","Verifies TPM 2.0 measured-boot integrity and remote attestation with tpm2-tools -- reading PCRs (tpm2_pcrread), replaying the boot event log, generating and checking signed quotes (tpm2_quote\u002Ftpm2_checkquote), and sealing secrets to a PCR policy. Use to confirm a system booted trusted firmware\u002Fkernel for Zero Trust device posture, detect boot-chain tampering via PCR drift, or build a golden-value baseline for fleet attestation.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-tpm-measured-boot-attestation\u002FSKILL.md",[137],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[139,127,140,141,116,142,34,119,143,144,145,146,147,148,149,150,151,152,153,154],"boot","TPM","validating tpm measured boot attestation","policy","verification","ZeRO","firmware","Tools","measured-boot","PCR","integrity","secrets","remote-attestation","tpm2-tools","integrity-verification","trusted-computing",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":159,"categories":160,"keywords":165,"publishedAt":44},"01M6AGDCW0Y4FXZ3362GT1941M","validating-backup-integrity-for-recovery","Validates backup integrity through cryptographic hash verification, automated restore testing, corruption detection, and recoverability checks to confirm backups are reliable for disaster recovery and ransomware response. Use before relying on backups for recovery, when building post-backup validation pipelines, auditing backup infrastructure for compliance, or checking immutable\u002Fair-gapped backups for silent corruption or tampering.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-backup-integrity-for-recovery\u002FSKILL.md",[161,164],{"categoryNo":162,"categoryName":163,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[149,166,167,168,169,34,170,171,143,172,173,174,175,176,177,178,179,180,181,182],"backup","recovery","validating backup integrity for recovery","testing","infrastructure","validation","compliance","hash-verification","incident-response","ransomware","cryptocurrency","detection","t1078","t1490","immutable","disaster-recovery","restore-testing",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":187,"categories":188,"keywords":190,"publishedAt":44},"01M6AGD9GBG2KZ336AE763J3WH","triaging-windows-with-kape","Runs KAPE (Kroll Artifact Parser and Extractor) to collect targeted forensic artifacts (registry hives, $MFT, event logs, prefetch, browser data) via Targets and parse them with Modules wrapping Eric Zimmerman's EZ Tools (PECmd, MFTECmd, RECmd). Use during early incident containment\u002Ftriage when full disk imaging is impractical but a defensible, parseable Windows artifact set is needed quickly, including at-scale remote collection.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-windows-with-kape\u002FSKILL.md",[189],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[191,192,193,34,194,195,196,197,198,199,200,201,202,203,204,205,146,206,207,208],"windows","kape","triaging windows with kape","registry","browser","logs","windows-forensics","dfir","mft","mftecmd","data","prefetch","eric-zimmerman","digital-forensics","SET","collection","pecmd","artifact-collection",{"skillNo":210,"name":211,"nameZh":6,"description":212,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":213,"categories":214,"keywords":216,"publishedAt":44},"01M6AGD5PW5J4EVZM958WD74ZQ","triaging-vulnerabilities-with-ssvc-framework","Triages and prioritizes vulnerabilities with CISA's Stakeholder-Specific Vulnerability Categorization (SSVC) decision tree, weighing exploitation status (via the CISA KEV catalog and FIRST EPSS API), technical impact, automatability, and mission prevalence to output Track\u002FTrack*\u002FAttend\u002FAct decisions. Use when prioritizing vulnerability scan results (OpenVAS, Nessus, Qualys) for remediation planning beyond raw CVSS scores.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-vulnerabilities-with-ssvc-framework\u002FSKILL.md",[215],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[217,218,219,34,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235],"vulnerabilities","framework","triaging vulnerabilities with ssvc framework","status","planning","CISA","vulnerability-management","risk-management","nessus","qualys","openvas","cvss","remediation","risk","vulnerability","api","prioritization","ssvc","decision-tree",{"skillNo":237,"name":238,"nameZh":6,"description":239,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":240,"categories":241,"keywords":243,"publishedAt":44},"01M6AGD24TTQQM4CXG69E3B9TJ","triaging-security-incident","Performs initial triage of security incidents using the NIST SP 800-61r3 and SANS PICERL frameworks, classifying incident type, assigning priority by business impact, and routing to the appropriate response team. Use when a SIEM\u002FEDR alert needs human classification, concurrent alerts must be prioritized, or a user report or threat-intel IOC match requires initial incident categorization.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-security-incident\u002FSKILL.md",[242],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[116,244,34,245,246,247,38,248,249,250,251,178,252,179,253,254,255,256,257,258],"triaging security incident","siem","file","ioc","NIST-800-61","NIST","severity","edr","execution","analysis","classification","severity-classification","incident-triage","SANS-PICERL","SOC-operations"]