Query Details

HUNT 15 Identity Ops Anomaly Deep Dive

Query

// Hunt     : Hunt - Identity Operation Volume Anomaly Deep-Dive (30 Days)
// Tactics  : Discovery, Impact, DefenseEvasion
// MITRE    : T1078, T1580
// Purpose  : For every identity active in the environment, compute daily write/delete/action operation counts and flag days where the volume significantly exceeds that identity's personal baseline. Use to investigate Rule-17 alerts, identify pre-attack reconnaissance bursts, or find compromised accounts that have been quietly abusing access over weeks.
//==========================================================================================

let ExcludedPatterns = dynamic(["terraform", "bicep", "pipeline", "github", "pulumi",
    "devops", "arm-deployment"]);
let AzurePlatformIPs = dynamic(["168.63.", "169.254."]);
// Daily operation counts per identity
let DailyOps = AzureActivity
    | where TimeGenerated > ago(30d)
    | where ActivityStatusValue =~ "Success"
    | where OperationNameValue has_any ("WRITE", "DELETE", "ACTION")
    | where not(OperationNameValue has_any ("READ", "LIST", "GET", "LISTKEYS"))
    | where isnotempty(Caller) and isnotempty(CallerIpAddress)
    | where not(CallerIpAddress has_any (AzurePlatformIPs))
    | where not(tolower(Caller) has_any (ExcludedPatterns))
    | summarize DailyCount = count() by Caller, Day = bin(TimeGenerated, 1d);
// Per-identity baseline stats (using the first 23 days as baseline)
let Baseline = DailyOps
    | where Day < ago(7d)
    | summarize
        AvgDailyOps = avg(DailyCount),
        StdDevOps   = stdev(DailyCount),
        SampleDays  = dcount(Day)
        by Caller
    | where SampleDays >= 3;
// Recent 7-day window
let RecentOps = DailyOps
    | where Day >= ago(7d);
RecentOps
| join kind=inner Baseline on Caller
| extend DeviationScore = iff(
    StdDevOps > 0,
    (DailyCount - AvgDailyOps) / StdDevOps,
    toreal(DailyCount))
// Tuned: require a meaningful daily volume floor so a modest spike from a tiny baseline
// doesn't surface as a large-sigma "anomaly". Low-baseline fallback raised 10 -> 20.
| where (DeviationScore >= 2.5 and DailyCount >= 15)
    or (AvgDailyOps < 1 and DailyCount >= 20)
| project
    Day,
    Caller,
    DailyCount,
    AvgDailyOps  = round(AvgDailyOps, 1),
    StdDevOps    = round(StdDevOps, 1),
    DeviationScore = round(DeviationScore, 1)
| order by DeviationScore desc, DailyCount desc

Explanation

This query is designed to identify unusual activity patterns for user identities in an Azure environment over the past 30 days. Here's a simplified breakdown:

  1. Purpose: The query aims to detect days when a user's write, delete, or action operations significantly exceed their typical activity levels. This can help identify potential security threats, such as reconnaissance activities or compromised accounts.

  2. Excluded Patterns: Certain patterns related to automated processes (e.g., "terraform", "github") and Azure platform IPs are excluded to focus on potentially suspicious user activity.

  3. Daily Operation Counts: The query calculates the number of successful write, delete, or action operations performed by each user daily, excluding read or list operations.

  4. Baseline Calculation: For each user, a baseline of average daily operations and standard deviation is calculated using data from the first 23 days of the 30-day period. This baseline helps determine what is "normal" for each user.

  5. Recent Activity Analysis: The query examines the last 7 days of activity and compares it to the baseline. It calculates a "Deviation Score" to measure how much a day's activity deviates from the user's average.

  6. Anomaly Detection: Days are flagged as anomalous if:

    • The deviation score is 2.5 or higher, and the daily count is at least 15 operations.
    • The average daily operations are less than 1, but the daily count is 20 or more.
  7. Output: The query outputs the day, user, daily operation count, average daily operations, standard deviation, and deviation score for flagged anomalies, sorted by the highest deviation score and daily count.

This process helps security teams focus on days with unusual user activity, potentially indicating security incidents.

Details

David Alonso profile picture

David Alonso

Released: July 27, 2026

Tables

AzureActivity

Keywords

AzureActivityCallerIpAddressOperationNameValueTimeGenerated

Operators

letdynamicago=~has_anyisnotemptytolowersummarizecountbinavgstdevdcountjoinkind=innerextendifftorealwhereorprojectroundorder bydesc

MITRE Techniques

Actions

GitHub