T1606.001 Microsoft Sentinel · KQL

Detect Web Cookies in Microsoft Sentinel

Adversaries may forge web cookies to gain unauthorized access to web applications or internet services. Unlike cookie theft (T1539), forged cookies are newly crafted by the adversary using stolen cryptographic material such as HMAC signing keys, private keys, or application secrets. Common targets include JWT bearer tokens, Flask session cookies (signed with itsdangerous using SECRET_KEY), Django session tokens, and platform-specific SaaS session identifiers. Because forged cookies appear as valid, trusted session credentials, they can bypass multi-factor authentication — the application trusts the cookie without re-challenging the user. The SolarWinds (SUNBURST) attack demonstrated this technique at scale when UNC2452/Dark Halo forged SAML assertion cookies after stealing ADFS signing certificates, enabling persistent access to cloud tenants that bypassed MFA entirely. Detection focuses on authentication anomalies in identity provider logs (sessions appearing from new locations without prior interactive authentication), endpoint activity where signing key material is accessed prior to token generation, and web server log patterns indicating session anomalies such as the same session ID appearing from multiple IPs.

MITRE ATT&CK

Tactic
Credential Access
Technique
T1606 Forge Web Credentials
Sub-technique
T1606.001 Web Cookies
Canonical reference
https://attack.mitre.org/techniques/T1606/001/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
// T1606.001 — Forged Web Cookie Detection via Azure AD Authentication Anomalies
// Three complementary detection branches targeting different forgery indicators

// Branch 1: Non-interactive sign-ins with anomalous token risk signals
// 'anomalousToken' risk detail fires when Microsoft detects unusual JWT characteristics
let AnomalousTokenSignIns = AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(24h)
| where RiskDetail in ("anomalousToken", "unfamiliarFeatures", "maliciousIPAddress", "suspiciousIPAddress")
    or RiskLevelDuringSignIn in ("high", "medium")
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName,
          TokenIssuerType, AuthenticationProtocol,
          RiskDetail, RiskLevelDuringSignIn, CorrelationId,
          DetectionBranch = "AnomalousToken";

// Branch 2: Successful single-factor authentication from anonymizing network
// Forged cookies used from Tor/anonymized IPs bypassing MFA Conditional Access
let AnonymousNetworkCookieAuth = SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| where NetworkLocationDetails has_any ("anonymizedIPAddress", "tor")
| where AuthenticationRequirement == "singleFactorAuthentication"
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName,
          NetworkLocationDetails, AuthenticationRequirement,
          ConditionalAccessStatus, CorrelationId,
          DetectionBranch = "AnonymousNetworkAuth";

// Branch 3: Same session correlation ID used from multiple distinct source IPs
// Indicates forged cookie being simultaneously used from multiple attacker hosts
let MultiIPSession = SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| summarize
    UniqueIPCount = dcount(IPAddress),
    IPList = make_set(IPAddress, 5),
    LocationList = make_set(Location, 5),
    SignInCount = count(),
    SessionStart = min(TimeGenerated),
    SessionEnd = max(TimeGenerated)
    by UserPrincipalName, AppDisplayName, CorrelationId
| where UniqueIPCount > 1
| where datetime_diff("minute", SessionEnd, SessionStart) < 120
| project SessionStart, UserPrincipalName, AppDisplayName,
          UniqueIPCount, IPList, LocationList, SignInCount, CorrelationId,
          DetectionBranch = "MultiIPSession";

// Union all branches
AnomalousTokenSignIns
| union AnonymousNetworkCookieAuth
| union (
    MultiIPSession
    | project TimeGenerated = SessionStart, UserPrincipalName,
              IPAddress = tostring(IPList), AppDisplayName,
              RiskDetail = "MultipleIPsInSession", RiskLevelDuringSignIn = "medium",
              TokenIssuerType = "", AuthenticationProtocol = "",
              NetworkLocationDetails = tostring(LocationList),
              AuthenticationRequirement = "", ConditionalAccessStatus = "",
              CorrelationId, DetectionBranch
)
| sort by TimeGenerated desc
high severity medium confidence

Detects potential forged web cookie usage through three complementary branches targeting Azure AD authentication telemetry. Branch 1 uses AADNonInteractiveUserSignInLogs to identify token-based sign-ins flagged with Microsoft Identity Protection risk signals — the 'anomalousToken' risk detail specifically fires when Microsoft detects a JWT with unusual characteristics (unexpected signing algorithm, non-standard claims, or mismatched token attributes). Branch 2 targets successful single-factor authentications from anonymizing networks (Tor, known anonymized IPs), a common pattern when attackers deploy forged cookies from C2 infrastructure while obscuring their origin. Branch 3 identifies the same CorrelationId appearing with multiple distinct source IPs within a 2-hour window, indicating a forged cookie being simultaneously used from multiple attacker-controlled hosts.

Data Sources

Logon Session: Logon Session CreationWeb Credential: Web Credential UsageApplication Log: Application Log ContentAzure Active Directory: Non-Interactive Sign-in LogsMicrosoft Identity Protection: Risk Events

Required Tables

AADNonInteractiveUserSignInLogsSigninLogs

False Positives & Tuning

  • Corporate VPN users whose traffic egresses through shared or anonymized IP ranges — establish Conditional Access Named Locations for known corporate VPN egress IPs and exclude them from Branch 2
  • Mobile or desktop applications using OAuth token refresh flows that generate non-interactive sign-ins from changing IPs as users roam between WiFi and cellular networks — review DeviceDetail and AppDisplayName to confirm legitimate client patterns
  • Office 365 service accounts and automation scripts performing scheduled tasks can trigger non-interactive high-risk sign-in signals due to unusual IP ranges or off-hours scheduling
  • Users with international travel whose sessions span multiple countries — correlate with HR travel records or look for preceding interactive re-authentication events
  • Azure AD Identity Protection 'anomalousToken' risk detail may fire on legitimate tokens issued by older authentication library versions that produce non-standard claim structures
Download portable Sigma rule (.yml)

Other platforms for T1606.001


Testing Methodology

Validate this detection against 5 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Flask Session Cookie Forgery with Known Secret Key

    Expected signal: On Linux: process creation for python3 with command line containing 'itsdangerous', 'URLSafeTimedSerializer', 'forged'. Sysmon for Linux / auditd will capture the process execution. On Windows: DeviceProcessEvents would show python.exe or python3.exe with the script content in the command line arguments if run via -c flag. No network events are generated (offline forgery) — the forged cookie must be injected into a subsequent HTTP request to trigger authentication events in web server logs.

  2. Test 2JWT Forgery via Weak HMAC Secret Brute Force and Re-Signing

    Expected signal: Process creation for python3 with PyJWT library import visible in command line or process arguments. On Windows with Sysmon: DeviceProcessEvents with python.exe or python3.exe. No network telemetry is generated during the offline forgery stage. When the forged JWT is subsequently used in HTTP Authorization headers against the target application, web server access logs will record the authentication attempt.

  3. Test 3Browser Cookie Injection for Session Hijacking via Curl

    Expected signal: Sysmon Event ID 3 (Network Connection): curl process making TCP connection to TARGET_URL. Web server access logs (IIS W3CIISLog or Apache access log via syslog sourcetype) will record the request with the Cookie header value, source IP, and User-Agent string. Web proxy logs (stream:http sourcetype if Splunk stream is deployed) will capture the full HTTP request including cookie headers. Azure AD or application auth logs will record the attempted authentication if the web application validates the cookie against an identity provider.

  4. Test 4JWT Algorithm Confusion Attack (None Algorithm)

    Expected signal: Process creation for python3 with base64 and json module usage. The output is the forged JWT token string. On endpoints with Sysmon: DeviceProcessEvents with python command line content. When the 'alg: none' token is submitted to a vulnerable application, the web server logs will show successful authentication. Modern applications and Azure AD reject 'alg: none' tokens, but vulnerable on-premise applications may not.

  5. Test 5Simulate Cookie Forgery Detection — Azure AD Risk Event Trigger

    Expected signal: Azure AD SigninLogs entry for the test account with IPAddress showing Tor exit node, NetworkLocationDetails containing 'anonymizedIPAddress', and RiskLevelDuringSignIn set to 'medium' or 'high' by Identity Protection. The sign-in will appear in Entra ID > Sign-in logs and should be ingested into Microsoft Sentinel's SigninLogs table within 5–15 minutes.

Unlock Pro Content

Get the full detection package for T1606.001 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections