Common Patterns
Sigma Rule Skeleton
title: <Detection Name>
id: <UUID>
status: experimental
description: <What this detects>
references:
- <URL or CTI report reference>
author: CTI Analyst
date: 2025/01/01
tags:
- attack.<tactic>
- attack.<technique_id> # e.g. attack.t1053, attack.t1059
logsource:
category: <process_creation | network_connection | file_event | ...>
product: <windows | linux | azure>
detection:
selection:
FieldName|<modifier>: <value>
condition: selection
falsepositives:
- <Known benign scenarios>
level: mediumGeneric KQL Query Pattern
TableName
| where ColumnName == "value" or ColumnName contains "partial"
| project TimeGenerated, RelevantColumn1, RelevantColumn2
| take 10
Always discover table names with list_kusto_tables() and column names with get_table_schema(table) before writing queries. Do not assume column names.
Investigation Decision Tree
- Query returns 0 rows? → Check column names against schema (exact match required) → Broaden filters:
containsinstead of==→ Sample the table to see what values actually exist → Remove time-based filters to test without date constraints - Query returns errors? → Verify table name exists via
list_kusto_tables()→ Check for KQL syntax issues (missing pipes, wrong operators) → For nested/JSON columns, usetostring()to extract values - Not sure which table to use? → List all tables, read their schemas, sample a few rows → Let the detection objective and CTI report guide your choice
Common Mistakes to Avoid
- Skipping CTI reports and going straight to data exploration
- Guessing column names instead of checking the schema first
- Writing overly specific queries that return 0 rows
- Not including MITRE technique IDs in the Sigma rule tags
- Submitting without calling validate_output_json