Detection rules › Kusto
Netskope - New Risky App Access vs 7-Day Baseline
Compares today's accessed applications against a 7-day baseline and triggers alerts when users access new risky applications not seen before.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access | T1199 Trusted Relationship |
| Discovery | T1526 Cloud Service Discovery |
Rule body kusto
id: ba66b81c-2cf7-4c53-9db0-e8b6f537704a
name: Netskope - New Risky App Access vs 7-Day Baseline
description: |
Compares today's accessed applications against a 7-day baseline and triggers alerts when users access new risky applications not seen before.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: NetskopeWebTxConnector
dataTypes:
- NetskopeWebTransactions_CL
queryFrequency: 1d
queryPeriod: 8d
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- Discovery
relevantTechniques:
- T1199
- T1526
query: |
let lookbackPeriod = 7d;
let currentPeriod = 1d;
let baseline = NetskopeWebTransactions_CL
| where TimeGenerated between (ago(lookbackPeriod) .. ago(currentPeriod))
| where isnotempty(CsUsername) and isnotempty(XCsApp)
| summarize BaselineApps = make_set(XCsApp) by CsUsername;
let current = NetskopeWebTransactions_CL
| where TimeGenerated > ago(currentPeriod)
| where isnotempty(CsUsername) and isnotempty(XCsApp)
| where XCsAppCcl =~ 'poor' or XCsAppCcl =~ 'low' or XCsAppCcl =~ 'medium' or XCsAppCci < 70
| summarize
CurrentApps = make_set(XCsApp),
arg_max(TimeGenerated, XCsAppCcl, XCsAppCci, XCsAppCategory)
by CsUsername, XCsApp;
current
| join kind=leftouter baseline on CsUsername
| extend BaselineApps = coalesce(BaselineApps, dynamic([]))
| where not(set_has_element(BaselineApps, XCsApp))
| where isnotempty(XCsApp)
| where XCsAppCci < 70 or XCsAppCcl =~ 'poor' or XCsAppCcl =~ 'low'
| project
TimeGenerated,
User = CsUsername,
NewRiskyApp = XCsApp,
AppCCL = XCsAppCcl,
AppCCI = XCsAppCci,
AppCategory = XCsAppCategory,
BaselineAppCount = array_length(BaselineApps)
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: User
- entityType: CloudApplication
fieldMappings:
- identifier: Name
columnName: NewRiskyApp
version: 1.0.0
kind: Scheduled
Stages and Predicates
Parameters
let lookbackPeriod = 7d;
let currentPeriod = 1d;
Let binding: baseline
let baseline = NetskopeWebTransactions_CL
| where TimeGenerated between (ago(lookbackPeriod) .. ago(currentPeriod))
| where isnotempty(CsUsername) and isnotempty(XCsApp)
| summarize BaselineApps = make_set(XCsApp) by CsUsername;
Derived from lookbackPeriod, currentPeriod.
The stages below define let current (the rule's main pipeline source).
Stage 1: source
NetskopeWebTransactions_CL
Stage 2: where
| where TimeGenerated > ago(currentPeriod)
Stage 3: where
| where isnotempty(CsUsername) and isnotempty(XCsApp)
Stage 4: where
| where XCsAppCcl =~ 'poor' or XCsAppCcl =~ 'low' or XCsAppCcl =~ 'medium' or XCsAppCci < 70
Stage 5: summarize
| summarize
CurrentApps = make_set(XCsApp),
arg_max(TimeGenerated, XCsAppCcl, XCsAppCci, XCsAppCategory)
by CsUsername, XCsApp
The stages below run on current (the outer pipeline).
Stage 6: join
current
| join kind=leftouter baseline on CsUsername
Stage 7: extend
| extend BaselineApps = coalesce(BaselineApps, dynamic([]))
Stage 8: where
| where not(set_has_element(BaselineApps, XCsApp))
Stage 9: where
| where isnotempty(XCsApp)
Stage 10: where
| where XCsAppCci < 70 or XCsAppCcl =~ 'poor' or XCsAppCcl =~ 'low'
Stage 11: project
| project
TimeGenerated,
User = CsUsername,
NewRiskyApp = XCsApp,
AppCCL = XCsAppCcl,
AppCCI = XCsAppCci,
AppCategory = XCsAppCategory,
BaselineAppCount = array_length(BaselineApps)
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
XCsApp | eq | BaselineApps |
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.
| Field | Kind | Values |
|---|---|---|
CsUsername | is_not_null | |
XCsApp | is_not_null | |
XCsAppCci | lt |
|
XCsAppCcl | eq |
|
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.
| Field | Source |
|---|---|
AppCCI | project |
AppCCL | project |
AppCategory | project |
BaselineAppCount | project |
NewRiskyApp | project |
TimeGenerated | project |
User | project |