Detection rules › Kusto

Netskope - Repeated or Critical Policy Violations

Status
available
Severity
high
Time window
1h
Group by
CsUsername, XCCountry, XCDevice
Source
github.com/Azure/Azure-Sentinel

Detects users with repeated policy violations or critical policy blocks. Monitors policy enforcement effectiveness and compliance.

MITRE ATT&CK coverage

Rule body kusto

id: dacab67e-fcf3-41c6-a191-579c7be1814d
name: Netskope - Repeated or Critical Policy Violations
description: |
  Detects users with repeated policy violations or critical policy blocks. Monitors policy enforcement effectiveness and compliance.
severity: High
status: Available
requiredDataConnectors:
  - connectorId: NetskopeWebTxConnector
    dataTypes:
      - NetskopeWebTransactions_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - DefenseEvasion
  - Exfiltration
relevantTechniques:
  - T1562
  - T1048
query: |
  let violationThreshold = 5;
  NetskopeWebTransactions_CL
  | where TimeGenerated > ago(1h)
  | where isnotempty(CsUsername)
  | where isnotempty(XPolicyAction) and isnotempty(XPolicyName)
  | where XPolicyAction =~ 'block' or XPolicyAction =~ 'alert'
  | summarize 
      ViolationCount = count(),
      Policies = make_set(XPolicyName),
      PolicyActions = make_set(XPolicyAction),
      Apps = make_set(XCsApp),
      Hosts = make_set(CsHost),
      Activities = make_set(XCsAppActivity),
      BlockCount = countif(XPolicyAction =~ 'block'),
      AlertCount = countif(XPolicyAction =~ 'alert'),
      FirstViolation = min(TimeGenerated),
      LastViolation = max(TimeGenerated)
      by CsUsername, XCCountry, XCDevice
  | where ViolationCount >= violationThreshold or BlockCount > 0
  | extend ViolationSeverity = case(
      BlockCount > 10, 'Critical',
      BlockCount > 5, 'High',
      ViolationCount > 20, 'High',
      ViolationCount > 10, 'Medium',
      'Low')
  | project 
      TimeGenerated = LastViolation,
      User = CsUsername,
      TotalViolations = ViolationCount,
      BlockedAttempts = BlockCount,
      AlertedActions = AlertCount,
      ViolatedPolicies = Policies,
      PolicyActions,
      ApplicationsInvolved = Apps,
      TargetHosts = Hosts,
      Activities,
      Country = XCCountry,
      Device = XCDevice,
      ViolationSeverity,
      FirstOccurrence = FirstViolation,
      LastOccurrence = LastViolation
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: User
version: 1.0.0
kind: Scheduled

Stages and Predicates

Parameters

let violationThreshold = 5;

Stage 1: source

NetskopeWebTransactions_CL

Stage 2: where

| where TimeGenerated > ago(1h)

Stage 3: where

| where isnotempty(CsUsername)

Stage 4: where

| where isnotempty(XPolicyAction) and isnotempty(XPolicyName)

Stage 5: where

| where XPolicyAction =~ 'block' or XPolicyAction =~ 'alert'

Stage 6: summarize

| summarize 
    ViolationCount = count(),
    Policies = make_set(XPolicyName),
    PolicyActions = make_set(XPolicyAction),
    Apps = make_set(XCsApp),
    Hosts = make_set(CsHost),
    Activities = make_set(XCsAppActivity),
    BlockCount = countif(XPolicyAction =~ 'block'),
    AlertCount = countif(XPolicyAction =~ 'alert'),
    FirstViolation = min(TimeGenerated),
    LastViolation = max(TimeGenerated)
    by CsUsername, XCCountry, XCDevice

Stage 7: where

| where ViolationCount >= violationThreshold or BlockCount > 0

Stage 8: extend

| extend ViolationSeverity = case(
    BlockCount > 10, 'Critical',
    BlockCount > 5, 'High',
    ViolationCount > 20, 'High',
    ViolationCount > 10, 'Medium',
    'Low')
ViolationSeverity =
ifBlockCount > 10'Critical'
elifBlockCount > 5'High'
elifViolationCount > 20'High'
elifViolationCount > 10'Medium'
else'Low'

Stage 9: project

| project 
    TimeGenerated = LastViolation,
    User = CsUsername,
    TotalViolations = ViolationCount,
    BlockedAttempts = BlockCount,
    AlertedActions = AlertCount,
    ViolatedPolicies = Policies,
    PolicyActions,
    ApplicationsInvolved = Apps,
    TargetHosts = Hosts,
    Activities,
    Country = XCCountry,
    Device = XCDevice,
    ViolationSeverity,
    FirstOccurrence = FirstViolation,
    LastOccurrence = LastViolation

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
BlockCountgt
  • 0 transforms: cased
CsUsernameis_not_null
  • (no value, null check)
ViolationCountge
  • 5 transforms: cased
XPolicyActioneq
  • alert
  • block
XPolicyActionis_not_null
  • (no value, null check)
XPolicyNameis_not_null
  • (no value, null check)

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
Activitiesproject
AlertedActionsproject
ApplicationsInvolvedproject
BlockedAttemptsproject
Countryproject
Deviceproject
FirstOccurrenceproject
LastOccurrenceproject
PolicyActionsproject
TargetHostsproject
TimeGeneratedproject
TotalViolationsproject
Userproject
ViolatedPoliciesproject
ViolationSeverityproject