T1528

Steal Application Access Token

Adversaries may steal application access tokens as a means of acquiring credentials to access remote systems and resources. Application access tokens — including OAuth 2.0 tokens, Kubernetes service account tokens, cloud provider temporary credentials (Azure Managed Identity via IMDS, AWS STS instance role credentials, GCP service account tokens), and CI/CD pipeline secrets — authorize API requests on behalf of users or services. Token theft enables adversaries to impersonate legitimate identities, access cloud resources and SaaS platforms with the victim's permissions, and move laterally without requiring plaintext passwords. Real-world examples include APT29 stealing OAuth tokens via malicious application consent phishing, APT28 creating fraudulent OAuth apps masquerading as Google services, and threat actors exploiting compromised containers to extract Kubernetes service account tokens via the pod filesystem.

Microsoft Sentinel / Defender
kusto
// T1528 — Steal Application Access Token
// Multi-vector detection covering IMDS token requests, Kubernetes token access,
// OAuth token cache file access, and high-privilege OAuth consent grants.

// --- Vector 1: Cloud metadata service (IMDS) token requests from unexpected processes ---
let LegitIMDSAgents = dynamic([
  "waagent.exe", "WindowsAzureGuestAgent.exe", "WaAppAgent.exe",
  "MonAgentCore.exe", "HealthService.exe", "MMAExtensionHeartbeatService.exe",
  "AzureAttestService.exe", "azd.exe", "AzureCLI.exe"
]);
let IMDSTokenRequests = DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIP == "169.254.169.254"
| where RemoteUrl has_any ("metadata/identity", "latest/meta-data/iam/security-credentials", "computeMetadata/v1/instance/service-accounts", "metadata/instance")
| where InitiatingProcessFileName !in~ (LegitIMDSAgents)
| extend Vector = "IMDS Token Request"
| extend TokenPlatform = case(
    RemoteUrl has "metadata/identity", "Azure Managed Identity",
    RemoteUrl has "iam/security-credentials", "AWS Instance Role",
    RemoteUrl has "service-accounts", "GCP Service Account",
    "Cloud IMDS")
| extend RiskDetail = strcat("Unexpected process '", InitiatingProcessFileName, "' queried ", TokenPlatform, " IMDS endpoint")
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName,
          InitiatingProcessCommandLine, RemoteUrl, Vector, TokenPlatform, RiskDetail;

// --- Vector 2: Kubernetes service account token file reads ---
let LegitK8sProcesses = dynamic(["kubelet", "pause", "containerd-shim", "containerd-shim-runc-v2", "runc", "cri-o", "dockerd"]);
let K8sTokenAccess = DeviceFileEvents
| where Timestamp > ago(24h)
| where FolderPath has_any (
    "/var/run/secrets/kubernetes.io/serviceaccount",
    "/run/secrets/kubernetes.io",
    "/var/run/secrets/tokens")
| where FileName in~ ("token", "ca.crt")
| where InitiatingProcessFileName !in~ (LegitK8sProcesses)
| extend Vector = "Kubernetes Service Account Token"
| extend TokenPlatform = "Kubernetes"
| extend RiskDetail = strcat("Process '", InitiatingProcessFileName, "' read K8s service account token: ", FolderPath, "/", FileName)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName,
          InitiatingProcessCommandLine, FileName, FolderPath, Vector, TokenPlatform, RiskDetail;

// --- Vector 3: OAuth / cloud CLI token cache access by unexpected processes ---
let LegitTokenOwners = dynamic([
  "gcloud", "gcloud.exe", "aws", "aws.exe", "az", "az.exe",
  "gh", "gh.exe", "git", "git.exe", "Code.exe", "code",
  "terraform", "terraform.exe", "kubectl", "kubectl.exe"
]);
let TokenCachePatterns = dynamic([
  "application_default_credentials.json",
  "accessTokens.json", "azureProfile.json",
  "msal_token_cache.json", "msal_token_cache.bin",
  "TokenCache.dat", ".git-credentials", "hosts.yml"
]);
let TokenCacheAccess = DeviceFileEvents
| where Timestamp > ago(24h)
| where FileName has_any (TokenCachePatterns)
    or (FolderPath has_any (".config/gcloud", ".azure", "TokenCache") and FileName endswith ".json")
| where ActionType in~ ("FileRead", "FileAccessed", "FileModified")
| where InitiatingProcessFileName !in~ (LegitTokenOwners)
| extend Vector = "OAuth Token Cache Access"
| extend TokenPlatform = case(
    FolderPath has ".config/gcloud" or FileName has "gcloud", "GCP",
    FolderPath has ".aws" or FileName has "aws", "AWS",
    FolderPath has ".azure" or FileName has "azure" or FileName has "msal", "Azure",
    FolderPath has ".gh" or FileName has "hosts.yml", "GitHub",
    "OAuth/Cloud")
| extend RiskDetail = strcat("Process '", InitiatingProcessFileName, "' accessed ", TokenPlatform, " token cache: ", FileName)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName,
          InitiatingProcessCommandLine, FileName, FolderPath, Vector, TokenPlatform, RiskDetail;

// --- Vector 4: High-privilege OAuth consent grants in Azure AD ---
let HighRiskOAuthScopes = dynamic([
  "Mail.ReadWrite", "Mail.Read", "Files.ReadWrite.All",
  "User.Read.All", "Directory.ReadWrite.All",
  "offline_access", "full_access_as_user",
  "EWS.AccessAsUser.All", "Contacts.ReadWrite"
]);
let OAuthConsentGrants = AuditLogs
| where TimeGenerated > ago(24h)
| where OperationName in ("Consent to application", "Add app role assignment to service principal", "Add delegated permission grant", "Add OAuth2PermissionGrant")
| where Result == "success"
| extend InitiatedByUser = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatedByIP = tostring(InitiatedBy.user.ipAddress)
| extend TargetApp = tostring(TargetResources[0].displayName)
| extend RawProps = tostring(TargetResources[0].modifiedProperties)
| where RawProps has_any (HighRiskOAuthScopes)
| extend Vector = "OAuth High-Privilege Consent Grant"
| extend TokenPlatform = "Azure AD / Microsoft 365"
| extend RiskDetail = strcat("User '", InitiatedByUser, "' consented to high-privilege OAuth app '", TargetApp, "' from IP: ", InitiatedByIP)
| project TimeGenerated, InitiatedByUser, InitiatedByIP, TargetApp, OperationName, RawProps, Vector, TokenPlatform, RiskDetail;

// --- Union all vectors ---
union
  (IMDSTokenRequests  | project Timestamp, Source=DeviceName,  Actor=AccountName,       Process=InitiatingProcessFileName, CommandLine=InitiatingProcessCommandLine, Vector, TokenPlatform, RiskDetail),
  (K8sTokenAccess     | project Timestamp, Source=DeviceName,  Actor=AccountName,       Process=InitiatingProcessFileName, CommandLine=InitiatingProcessCommandLine, Vector, TokenPlatform, RiskDetail),
  (TokenCacheAccess   | project Timestamp, Source=DeviceName,  Actor=AccountName,       Process=InitiatingProcessFileName, CommandLine=InitiatingProcessCommandLine, Vector, TokenPlatform, RiskDetail),
  (OAuthConsentGrants | project Timestamp=TimeGenerated, Source=InitiatedByIP, Actor=InitiatedByUser, Process=TargetApp, CommandLine=RawProps, Vector, TokenPlatform, RiskDetail)
| sort by Timestamp desc
high severity medium confidence

Data Sources

Network: Network Connection Creation File: File Access Application Log: Application Log Content Cloud Service: Cloud Service Metadata Azure Active Directory: Audit Logs

Required Tables

DeviceNetworkEvents DeviceFileEvents AuditLogs

False Positives

  • Security scanning tools and vulnerability assessment agents that enumerate IMDS endpoints as part of cloud posture checks (e.g., Prisma Cloud, Wiz, Orca)
  • Developer workstations where developers legitimately use multiple cloud CLIs (gcloud, az, aws) and IDEs that access token caches on behalf of the user
  • Legitimate Kubernetes operators and custom controllers that mount and read service account tokens as part of their normal authentication flow to the Kubernetes API
  • CI/CD pipeline agents (GitHub Actions runner, GitLab Runner, Jenkins agent) that access cloud credentials and token caches as part of authorized deployment workflows
  • IT administration scripts that use OAuth tokens for legitimate bulk operations (e.g., Microsoft Graph scripts for user provisioning, Azure automation runbooks)

Unlock Pro Content

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

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections