Kusto (KQL) für Einsteiger: Abfragen für Sentinel und Defender

Kurzfassung: KQL (Kusto Query Language) ist die Abfragesprache hinter Microsoft Sentinel und Defender XDR und die wichtigste Einzelfähigkeit für Analysten, die im Microsoft-Stack arbeiten. Der Kern ist einfach: Eine Abfrage ist eine Pipeline, die von links nach rechts gelesen wird. Man beginnt mit einer Tabelle und schickt die Daten durch Operatoren, die filtern, formen und zusammenfassen, verbunden durch den senkrechten Strich. Sieben Operatoren (where, summarize, project, extend, join, parse, mv-expand) decken die meisten Fälle ab, und die wichtigste Regel lautet: früh filtern. Wer aus der SQL-Welt kommt, braucht wenige Wochen; der Unterschied ist, dass KQL streng linear ist, nicht deklarativ.

Kusto Query Language, kurz KQL, ist die Abfragesprache, die den Microsoft-Sicherheits-Stack antreibt: Microsoft Sentinel als SIEM, Defender XDR und die erweiterte Suche laufen alle auf KQL. Wer in einer Microsoft-Umgebung Alarme untersucht, Erkennungsregeln schreibt oder auf die Jagd geht, kommt an KQL nicht vorbei, und die Beherrschung der Sprache ist der Unterschied zwischen einem Analysten, der Alarmen hinterherläuft, und einem, der Bedrohungen findet, bevor sie eskalieren. Dieser Beitrag ist ein Einstieg ohne Vorwissen: die Grundstruktur einer Abfrage, die wichtigsten Operatoren mit Beispielen aus dem SOC-Alltag, die zeitbezogenen Funktionen, die KQL für Log-Daten so passend machen, und die Prinzipien, die aus einer langsamen Abfrage eine schnelle machen. Er ergänzt den Beitrag zu Sigma-Regeln, der die herstellerneutrale Ebene beschreibt; KQL ist die konkrete Sprache, in die eine Sigma-Regel für Sentinel übersetzt wird.

Der wichtigste Unterschied zu SQL, den man einmal verstehen muss, dann ist der Rest Vokabular: SQL ist deklarativ, die Klauseln SELECT, FROM, WHERE können in beliebiger Reihenfolge stehen. KQL ist eine strikt lineare Pipeline, die von links nach rechts und von oben nach unten gelesen wird. Jede Abfrage beginnt mit einer Tabelle, und dann fließen die Daten durch eine Kette von Operatoren, jeder getrennt durch einen senkrechten Strich (die Pipe). Jeder Operator bekommt die Tabelle des vorherigen, verändert sie und gibt sie an den nächsten weiter. Ein einfaches Beispiel:

KQL
SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == 4625
| summarize Fehlversuche = count() by Account
| sort by Fehlversuche desc

Gelesen von oben nach unten: Nimm die Tabelle SecurityEvent, behalte nur die Ereignisse der letzten Stunde, davon nur die fehlgeschlagenen Anmeldungen (4625), zähle sie pro Konto und sortiere absteigend. Das Ergebnis ist eine Liste der Konten mit den meisten Fehlanmeldungen in der letzten Stunde, die Grundlage der Password-Spraying-Erkennung. Wer diese Lesart verinnerlicht hat, kann jede KQL-Abfrage entziffern.

Die sieben Operatoren, die fast alles abdecken

OperatorWas er tut
whereFiltert Zeilen nach einer Bedingung. Der wichtigste Operator, und der, der so früh wie möglich stehen sollte.
summarizeFasst Zeilen zusammen und rechnet: zählen, verschiedene Werte zählen, Minimum, Maximum, gruppiert nach einem Feld.
projectWählt die Spalten aus, die im Ergebnis erscheinen. Hält die Ausgabe übersichtlich.
extendFügt eine berechnete Spalte hinzu, etwa aus zwei bestehenden Feldern.
joinVerbindet zwei Tabellen über ein gemeinsames Feld, um Daten aus verschiedenen Quellen zu korrelieren.
parseZerlegt ein unstrukturiertes Textfeld in einzelne Felder, häufig bei Log-Daten mit eingebetteten Informationen.
mv-expandZerlegt ein Feld, das eine Liste enthält, in einzelne Zeilen.

Diese sieben decken den Großteil der Sicherheitsfälle ab. Dazu kommen zwei Hilfsmittel, die den Alltag erleichtern: let, um am Anfang einer Abfrage einen Wert oder eine Teilabfrage zu benennen und später wiederzuverwenden, und render, um das Ergebnis als Diagramm auszugeben. Wer diese neun Bausteine kennt, schreibt die allermeisten Abfragen, die im Tier-1- und Tier-2-Alltag vorkommen.

Zeit ist der rote Faden

KQL ist für Zeitreihen und Log-Daten gebaut, und das zeigt sich an den Zeitfunktionen, die man ständig braucht. ago() bezeichnet einen Zeitpunkt in der Vergangenheit: ago(24h) ist vor 24 Stunden, ago(7d) vor sieben Tagen. between() grenzt einen Zeitraum ein. Und bin() rundet Zeitstempel auf feste Intervalle, was das Zählen über Zeitfenster ermöglicht:

KQL
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType != 0
| summarize Fehlanmeldungen = count() by bin(TimeGenerated, 1h)
| render timechart

Diese Abfrage zählt die fehlgeschlagenen Anmeldungen der letzten sieben Tage pro Stunde und zeichnet sie als Zeitdiagramm. Ein plötzlicher Ausschlag zeigt einen Angriff. Das bin(TimeGenerated, 1h) ist der Kern: Es gruppiert die Ereignisse in Stundenfenster, sodass aus einzelnen Zeilen eine zählbare Reihe wird. Genau dieses Muster steckt hinter fast jeder zeitbasierten Erkennung.

Die wichtigsten Tabellen

Eine Abfrage beginnt mit einer Tabelle, und zu wissen, welche Tabelle welche Daten enthält, ist die halbe Miete. Die wertvollsten für die Sicherheitserkennung:

  • SecurityEvent. Die weitergeleiteten Windows-Sicherheitsereignisse, also die Event-IDs wie 4624, 4625, 4688, 4698. Die Grundlage der meisten Windows-Erkennungen.
  • SigninLogs und AADNonInteractiveUserSignInLogs. Die Anmeldeereignisse aus Entra ID, die Grundlage für die Erkennung von übernommenen Konten und Token-Diebstahl.
  • AuditLogs. Änderungen im Verzeichnis, etwa neue Konten oder geänderte Gruppenmitgliedschaften.
  • OfficeActivity. Die Aktivitäten in Microsoft 365, etwa Postfachregeln und Dateizugriffe, wichtig für die Analyse eines kompromittierten Kontos.
  • DeviceProcessEvents und DeviceEvents. Die Endpunkt-Telemetrie aus Defender for Endpoint, das Gegenstück zu Sysmon im Microsoft-Stack.

Früh filtern: das wichtigste Prinzip

Wenn es eine einzige Regel gibt, die gutes von langsamem KQL trennt, dann diese: früh filtern. Das where gehört so weit nach oben wie möglich, idealerweise gleich nach der Tabelle und zuerst auf die Zeit, damit alle folgenden Operatoren nur noch mit den relevanten Daten arbeiten. Wer erst zusammenfasst und dann filtert, lässt die Maschine über Millionen Zeilen rechnen, die anschließend verworfen werden. Wer zuerst filtert, schickt nur die relevanten Zeilen durch die Pipeline. Dieselbe Disziplin, die eine gute Erkennungsregel von einer verrauschten trennt, trennt auch eine schnelle Abfrage von einer langsamen: spezifisch filtern, früh filtern, und gegen echte Daten prüfen, bevor man die Regel ausrollt. Das ist der Punkt, an dem KQL und Detection Engineering zusammenkommen.

Wie man KQL lernt

  1. Die Pipeline verstehen. Erst die Lesart von links nach rechts verinnerlichen, dann die sieben Operatoren. Alles Weitere baut darauf auf.
  2. An echten Daten üben. Im eigenen Homelab mit angebundenem Sentinel oder mit den kostenlosen Beispieldaten, die Microsoft bereitstellt. KQL lernt man durch Abfragen, nicht durch Lesen.
  3. Eine Bibliothek aufbauen. Bewährte Abfragen sammeln und dokumentieren, mit der Logik und dem Fehlalarm-Profil, damit der nächste Analyst sie versteht. Das ist derselbe Gedanke wie beim Detection Engineering.
  4. Die fertigen Beispiele nutzen. Sentinel bringt eine große Sammlung fertiger Abfragen für Analyse, Hunting und Arbeitsmappen mit, und die offizielle KQL-Referenz von Microsoft ist die verlässliche Quelle für die Operatoren.

Fazit

KQL ist die höchstwirksame Einzelfähigkeit für jeden, der im Microsoft-Sicherheits-Stack arbeitet, und der Einstieg ist leichter, als er aussieht: eine Pipeline von links nach rechts, sieben Operatoren, die fast alles abdecken, die Zeitfunktionen als roter Faden und das Prinzip, früh zu filtern. Wer die Grundstruktur verstanden hat und an echten Daten übt, wird in wenigen Wochen flüssig und öffnet sich damit einen großen Teil des SOC-Arbeitsmarkts, den reine Splunk-Analysten nicht bedienen können. Für ein Blue Team im Microsoft-Umfeld ist KQL das Werkzeug, mit dem aus Millionen Ereignissen die wenigen werden, die zählen, und die Sprache, in der fast jede Erkennung und jeder Hunt am Ende geschrieben wird.

NH

$ whoami

Norbert Hofmann

Cyber Defense Analyst im Security Operations Center eines Managed Security Service Providers. Red und Blue Teaming, Malware-Analyse, Incident Response und Security-Awareness-Trainings. Finalist bei „Deutschlands bester Hacker“ 2022, mehrere CVE-Einträge für WordPress-Plugins.