Skip to content

Commit 910dea7

Browse files
authored
Update summary-rules.md
1 parent fd5bf66 commit 910dea7

File tree

1 file changed

+0
-53
lines changed

1 file changed

+0
-53
lines changed

articles/sentinel/summary-rules.md

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -155,59 +155,6 @@ This section reviews common scenarios for creating summary rules in Microsoft Se
155155
156156
1. **Run a subsequent search or correlation with other data** to complete the attack story.
157157
158-
### Detect potential SPN scanning in your network
159-
160-
Detect potential Service Principal Name (SPN) scanning in your network traffic.
161-
162-
**Scenario**: You're a SOC engineer who needs to create a highly accurate detection for any SPN scanning performed by a user account. The detection currently does the following:
163-
164-
1. Looks for Security events with EventID 4796 (A Kerberos service ticket was requested).
165-
1. Creates a baseline with the number of unique tickets typically requested by a user account per day.
166-
1. Generates an alert when there's a major deviation from that baseline.
167-
168-
**Challenge**: The current detection runs on 14 days, or the maximum data lookback in the Analytics table, and creates many false positives. While the detection includes thresholds that are designed to prevent false positives, alerts are still generated for legitimate requests as long as there are more requests than usual. This might happen for vulnerability scanners, administration systems, and in misconfigured systems. On your team, there were so many false positives that they needed to turn off some of the analytics rules. To create a more accurate baseline, you'll need more than 14 days of baseline data.
169-
170-
The current detection also runs a summary query on a separate logic app for each alert. This involves extra work for the setup and maintenance of those logic apps, and incurs extra costs.
171-
172-
**Solution**: We recommend using summary rules to do the following:
173-
174-
1. Generate a daily summary of the count of unique tickets per user. This summarizes the `SecurityEvents` table data for EventID 4769, with extra filtering for specific user accounts.
175-
176-
1. In the summary rule, to generate potential SPN scanning alerts:
177-
178-
- Reference at least 30 days worth of summary data to create a strong baseline.
179-
- Apply `percentile()` in your query to calculate the deviation from the baseline
180-
181-
For example:
182-
183-
```kusto
184-
let starttime = 14d;
185-
let endtime = 1d;
186-
let timeframe = 1h;
187-
let threshold=10;
188-
let Kerbevent = SecurityEvent
189-
| where TimeGenerated between(ago(starttime) .. now())
190-
| where EventID == 4769
191-
| parse EventData with * 'TicketEncryptionType">' TicketEncryptionType "<" *
192-
| parse EventData with * 'ServiceName">' ServiceName "<" *
193-
| where ServiceName !contains "$" and ServiceName !contains "krbtgt"
194-
| parse EventData with * 'TargetUserName">' TargetUserName "<" *
195-
| where TargetUserName !contains "$@" and TargetUserName !contains ServiceName
196-
| parse EventData with * 'IpAddress">::ffff:' ClientIPAddress "<" *; let baseline = Kerbevent
197-
| where TimeGenerated >= ago(starttime) and TimeGenerated < ago(endtime)
198-
| make-series baselineDay=dcount(ServiceName) default=1 on TimeGenerated in range(ago(starttime), ago(endtime), 1d) by TargetUserName | mvexpand TimeGenerated , baselineDay
199-
| extend baselineDay = toint(baselineDay)
200-
| summarize p95CountDay = percentile(baselineDay, 95) by TargetUserName; let current = Kerbevent
201-
| where TimeGenerated between(ago(timeframe) .. now())
202-
| extend encryptionType = case(TicketEncryptionType in ("0x1","0x3"), "DES", TicketEncryptionType in ("0x11","0x12"), "AES", TicketEncryptionType in ("0x17","0x18"), "RC4", "Failure")
203-
| where encryptionType in ("AES","DES","RC4")
204-
| summarize currentCount = dcount(ServiceName), ticketsRequested=make_set(ServiceName), encryptionTypes=make_set(encryptionType), ClientIPAddress=any(ClientIPAddress), Computer=any(Computer) by TargetUserName; current
205-
| join kind=leftouter baseline on TargetUserName
206-
| where currentCount > p95CountDay*2 and currentCount > threshold
207-
| project-away TargetUserName1
208-
| extend context_message = strcat("Potential SPN scan performed by user ", TargetUserName, "\nUser generally requests ", p95CountDay, " unique service tickets in a day.", "\nUnique service tickets requested by user in the last hour: ", currentCount)
209-
```
210-
211158
### Generate alerts on threat intelligence matches against network data
212159
213160
Generate alerts on threat intelligence matches against noisy, high volume, and low-security value network data.

0 commit comments

Comments
 (0)