cloudflare/Azure-Sentinel
Publicmirrored fromhttps://github.com/cloudflare/Azure-Sentinel
Functions/BaselinePattern.txt
33lines · modecode
unknown
| 1 | // Baseline a pattern of interest |
| 2 | // Identify new occurrences of a pattern of interest versus history of occurrences of these patterns in a baseline period |
| 3 | // newInstances(timeRange:timespan, historicalBaselineTimerange:timespan) |
| 4 | // Parameters: |
| 5 | // timeRange : the timespan over which to return results. |
| 6 | // historicalBaselineTimerange: the baseline period timespan - instances of the pattern of interest that occur within this baseline period will not be included in the result set. |
| 7 | // |
| 8 | // This function assumes a prior step that defines an 'instanceSet' of patterns of interest, and the 'historicalFeature' ie the column over which the baselining is performed. |
| 9 | // |
| 10 | // Usage: |
| 11 | // newInstances(1d, 7d) | take 10 |
| 12 | // Return new instances of the pattern in 'instanceSet' that occurred in the last day, and did not occur in the prior 7 days. |
| 13 | // |
| 14 | // Example - assume wanting to surface new encoded powershell commands (ie the historical feature here is the encoded powershell command) |
| 15 | // Define your own instanceSet table and / historicalFeature column before calling this function. |
| 16 | //let instanceSet = SecurityEvent |
| 17 | //| where TimeGenerated >= ago(8d) |
| 18 | //| where NewProcessName endswith "powershell.exe" |
| 19 | //| where CommandLine contains "-encodedCommand" |
| 20 | //| parse CommandLine with * "-EncodedCommand " encodedCommand |
| 21 | //| project TimeGenerated, decodedCommand=base64_decodestring(substring(encodedCommand, 0, |
| 22 | // strlen(encodedCommand) - (strlen(encodedCommand) %8))), encodedCommand, |
| 23 | // historicalFeature=encodedCommand; |
| 24 | // |
| 25 | // This saved function does the join against the specified baseline period. |
| 26 | let newInstances = view (ResultRecentTimeSpan:timespan, BaselineWindow:timespan) { |
| 27 | let baselineStart = ago(ResultRecentTimeSpan) - BaselineWindow; |
| 28 | let baselineEnd = ago(ResultRecentTimeSpan); |
| 29 | instanceSet | where TimeGenerated >= ago(ResultRecentTimeSpan) |
| 30 | | join kind = anti (instanceSet | where TimeGenerated between(baselineStart..baselineEnd)) on historicalFeature |
| 31 | }; |
| 32 | //newInstances(1d, 7d) | take 10; |