IRQL – Incident Response Query Language (Sprache für Vorfallreaktionen)
Komponieren Sie IRQL-Funktionspipelines aus den Bausteinen Selektor, Extraktor und Anreicherer. IRQL verpackt rohe KQL-Sicherheitstabellen hinter absichtserkennenden, komponierbaren Funktionen, sodass Analysten (und LLMs) Jagden ausdrücken können, ohne Schemas, Cluster-Standorte oder Join-Schlüssel auswendig lernen zu müssen.
Aktivierungsauslöser
Verwenden Sie dieses Skill, wenn der Benutzer:
- Explizit IRQL,
Get_*,Extract_*oderEnrich_*-Funktionen erwähnt - "IRQL verwenden" oder "eine IRQL-Abfrage schreiben" sagt
- Eine komponierbare Jagdpipeline mit bekannten IRQL-Selektoren anfordert
Nicht aktivieren für allgemeine Sicherheitsabfragen (z. B. "fehlgeschlagene Anmeldungen finden"), es sei denn, der Benutzer bittet explizit um IRQL. Leiten Sie solche Anfragen stattdessen an azure-kusto weiter.
Kein Konverter von natürlicher Sprache zu IRQL. Dieses Skill komponiert IRQL-Funktionspipelines und kann grundlegende natürlichsprachliche Anfragen verarbeiten, die direkt auf bekannte Selektoren und einfache Filter abbilden. Für die allgemeine Umwandlung von NL zu KQL oder NL zu IRQL verwenden Sie ein spezielles Query-Generierungs-Skill (separat verfügbar).
IRQL-Funktionsüberprüfung
Überprüfen Sie vor der Generierung einer Pipeline, ob IRQL auf der Zieldatenbank verfügbar ist:
.show functions
| where Name startswith "Get_" or Name startswith "Extract_" or Name startswith "Enrich_"
| project Name
Wenn keine IRQL-Funktionen gefunden werden, informieren Sie den Benutzer, dass IRQL nicht auf der Zieldatenbank bereitgestellt ist, und schlagen Sie die Verwendung von azure-kusto für rohe KQL-Abfragen vor. IRQL-Funktionen sind eine Voraussetzung – dieses Skill stellt keine Basis-IRQL-Selektoren bereit.
Was IRQL ist
IRQL ist ein funktionsbasierter Dialekt auf Basis von KQL. Es bietet:
- Einheitliches Schema – verschiedene Sicherheitstabellen projizieren in konsistente Spaltennamen, unabhängig von der zugrunde liegenden Datenquelle
- Komponierbarkeit – kleine Funktionen verketten sich via
| invoke, um aus einfachen Schritten komplexe Jagden zu bauen - Portabilität – dieselbe IRQL-Pipeline funktioniert über verschiedene Cluster/Datenbanken; nur die
Get_*-Primitive müssen umadressiert werden
IRQL ist keine separate Sprache. Es sind KQL-Funktionen, die Sie aufrufen. Jedes gültige KQL funktioniert neben IRQL-Funktionen.
Bereitstellung von IRQL
IRQL-Funktionen sind gespeicherte KQL-Funktionen (.create-or-alter function). Sie müssen bereits auf der Zieldatenbank bereitgestellt sein, bevor dieses Skill Pipelines generieren kann.
Öffentlicher Beispielcluster (Funktionen vorinstalliert):
- Cluster:
https://kc7001.eastus.kusto.windows.net - Datenbanken:
ValdyTimes,JoJosHospital
Um IRQL auf einen neuen Cluster/eine neue Datenbank zu portieren, erstellen Sie Get_*-Selektoren, die Ihre Quelltabellen in das einheitliche Schema projizieren (Spaltennamen unten), und stellen Sie dann Extraktoren und Anreicherer bereit. Die Extraktoren und Anreicherer funktionieren unverändert, solange das Eingabeschema übereinstimmt.
Funktionskatalog
1. Selektoren – Get_*
Geben projizierte, schemavereinheitlichte Ansichten der Quelltabellen zurück. Standardmäßig die minimale Form verwenden; _All verwenden, wenn zusätzliche Spalten benötigt werden.
| Funktion | Spalten |
|---|---|
Get_Event_Authentication | EnvTime, Hostname, ClientIp, Username, Result |
Get_Event_Authentication_All | + Description, UserAgent, PasswordHash |
Get_Email | EnvTime, EmailSender, EmailRecipient, Subject, Url |
Get_Email_All | + ReplyTo, Verdict |
Get_Employees | Name, ClientIp, Email, Username, Hostname, Role |
Get_Employees_All | + HireDate, UserAgent, Domain |
Get_Event_FileCreation | EnvTime, Hostname, Filename, Path |
Get_Event_FileCreation_All | + Username, Sha256, ProcessName |
Get_Event_NetworkInbound | EnvTime, ClientIp, Url |
Get_Event_NetworkInbound_All | + Method, UserAgent, StatusCode |
Get_Event_NetworkOutbound | EnvTime, ClientIp, Url |
Get_Event_NetworkOutbound_All | + Method, UserAgent |
Get_Dns_All | EnvTime, Domain, ClientIp |
Get_Event_Process | EnvTime, ProcessCommandLine, ProcessName, Hostname, Username |
Get_Event_Process_All | + ParentProcessName, ParentProcessHash, ProcessHash |
Get_SecurityAlerts_All | EnvTime, AlertType, Severity, Description, Indicators |
Get_Network_Connection_All | EnvTime, SourceIp, SourcePort, DestinationIp, DestinationPort, Protocol, Bytes |
2. Extraktoren – Extract_*
Leiten eine neue Spalte aus einer vorhandenen ab. Nach einem Selektor aufrufen.
| Funktion | Eingabespalte | Fügt hinzu |
|---|---|---|
Extract_Email_Sender_Domain(T) | EmailSender | Domain |
Extract_Employee_Firstname(T) | Name | Firstname |
Extract_Event_Network_Domain(T) | Url | DomainName |
3. Anreicherer – Enrich_*
Left-Join-Helfer, die Kontext aus einer verwandten Tabelle anhängen.
| Funktion | Schlüsselspalte | Reichert an mit |
|---|---|---|
Enrich_Event_Authentication_Username(T) | Username | Authentifizierungsereignisse für Benutzer |
Enrich_Ip_Employee(T) | ClientIp | Mitarbeiteridentität aus IP |
Enrich_Username_Employee(T) | Username | Mitarbeiteridentität aus Benutzername |
Enrich_Ip_Domain(T) | ClientIp | DNS-Domänen, die zu IP aufgelöst wurden |
Enrich_Ip_Event_NetworkOutbound(T) | ClientIp | Ausgehende Netzwerke von IP |
Enrich_Ip_Network_Connection(T) | ClientIp | Netzwerkflüsse von IP |
4. Externe Anreicherung
| Funktion | Quelle | Voraussetzung |
|---|---|---|
Enrich_Sha256_VirusTotal(T) | VirusTotal-Dateibericht | API-Schlüssel + Callout-Richtlinie |
Get_CISA_KEV() / Enrich_CISA_KEV(T) | CISA-KEV-Katalog | Callout-Richtlinie |
Kompositionsregeln
Selektor -> Extraktor -> Filter -> Anreicherer -> Zusammenfassen/Projizieren
- Mit einem Selektor beginnen:
Get_Event_Authentication,Get_Emailusw. - Abgeleitete Felder extrahieren:
| invoke Extract_Email_Sender_Domain() - Auf das Signal filtern:
| where Result == "Failed Login" - Mit Kontext anreichern:
| invoke Enrich_Username_Employee() - Die Antwort zusammenfassen/projizieren
Immer mit | zwischen den Schritten pipen. Extraktoren und Anreicherer verwenden | invoke FunktionName().
Richtlinien zur Abfragegenerierung
- Den minimalen Selektor verwenden, es sei denn, zusätzliche Spalten werden benötigt → dann
_All - Extraktoren vor Anreicherern verketten (Extraktoren fügen Spalten hinzu, auf die Anreicherer schlüsseln können)
where-Filter so früh wie möglich platzierensummarizefür Aggregationen,projectfür die endgültige Spaltenauswahl verwenden- Mit
order by+takeenden, um die Ausgabe zu begrenzen
Beispiele
Für weitere Aufforderungen und ausgearbeitete Beispiele siehe references/EXAMPLES.md.
Brute-Force-Erkennung
Get_Event_Authentication
| where Result == "Failed Login"
| summarize FailedCount = count() by Username
| where FailedCount > 19
| invoke Enrich_Username_Employee()
| project Username, Name, Role, Email, FailedCount
| order by FailedCount desc
Phishing-Triage nach Empfänger-Seniorität
Get_Email
| invoke Extract_Email_Sender_Domain()
| project EnvTime, EmailSender, Domain, Username = EmailRecipient, Subject, Url
| invoke Enrich_Username_Employee()
| extend Seniority = case(
Role has_any ("CEO", "Chief", "Director", "VP", "President"), 3,
Role has_any ("Manager", "Lead", "Senior"), 2,
1)
| summarize
TotalEmails = count(),
SeniorityScore = sum(Seniority),
Recipients = make_set(Name, 50),
DistinctRecipients = dcount(Username)
by Domain
| where DistinctRecipients >= 2
| order by SeniorityScore desc
| take 20
Post-Exploitation-Pivot von einem Indikator aus
let victims =
Get_Event_FileCreation_All
| where Filename has "<INDICATOR>"
| distinct Hostname;
Get_Event_Process
| where Hostname in (victims)
| where ProcessCommandLine has_any ("rundll32", "regsvr32", "powershell", "systeminfo")
| project EnvTime, Hostname, Username, ProcessName, ProcessCommandLine
| order by EnvTime asc
Verdächtiger ausgehender Datenverkehr, angereichert mit Identität
Get_Event_NetworkOutbound
| invoke Extract_Event_Network_Domain()
| where DomainName has_any ("<SUSPICIOUS_DOMAIN_1>", "<SUSPICIOUS_DOMAIN_2>")
| invoke Enrich_Ip_Employee()
| project EnvTime, Name, Role, DomainName, Url, ClientIp
| order by EnvTime desc
Anomale Authentifizierung von externen IPs
Get_Event_Authentication_All
| where not(ClientIp startswith "10.") and not(ClientIp startswith "192.168.")
| summarize
Attempts = count(),
Failures = countif(Result == "Failed Login"),
Users = make_set(Username)
by ClientIp
| order by Failures desc
| take 20
Verwendete MCP-Tools
| Tool | Zweck |
|---|---|
kusto_query | Ausführen von IRQL-Pipelines gegen eine Kusto-Datenbank |
kusto_table_schema_get | Entdecken verfügbarer Tabellen und Spalten |
kusto_cluster_list | Auflisten verfügbarer ADX-Cluster |
kusto_database_list | Auflisten von Datenbanken in einem Cluster |
Öffnen von Abfragen im Kusto Explorer (nur Windows)
Optionale Komfortfunktion. Der Standard-Workflow besteht darin, das KQL im Chat auszugeben und den Benutzer es manuell in den Kusto Explorer oder die VS Code Kusto-Erweiterung kopieren zu lassen. Der automatische Start ist nur per Opt-in möglich.
Geben Sie immer die vollständige KQL-Abfrage in der Chat-Antwort aus, wobei Schritt 1 (verbinden) und Schritt 2 (Abfrage) klar gekennzeichnet sind:
// Schritt 1: Mit Ihrem Cluster verbinden (überspringen, falls bereits verbunden)
// Beispiel: Auskommentieren, um mit dem KC7-Trainingscluster zu verbinden
// #connect cluster('kc7001.eastus.kusto.windows.net').database('ValdyTimes')
// Oder durch Ihren eigenen Cluster ersetzen:
// #connect cluster('<YOUR_CLUSTER>').database('<YOUR_DATABASE>')
// Schritt 2: Die folgende Abfrage ausführen
<KQL_QUERY>
Wenn der Benutzer bittet, die Abfrage im Kusto Explorer zu speichern oder zu öffnen, befolgen Sie das Verfahren in references/KUSTO_EXPLORER_LAUNCH.md. Wichtige Regeln:
ask_userverwenden, um vor dem Schreiben von Dateien oder dem Starten von ausführbaren Dateien eine Bestätigung einzuholen- Dateiinhalte im Chat anzeigen, damit der Benutzer sie vor dem Öffnen überprüfen kann
- Niemals Shell-Interpolation oder Here-Strings verwenden – Dateien via
Set-Content/Add-Contentschreiben - Niemals Abfragen in Browser-URLs codieren
- Unter macOS/Linux die
.kql-Datei speichern und die VS Code Kusto-Erweiterung oder den ADX Web Explorer vorschlagen - Für Graph-Visualisierung von IRQL-Daten siehe
azure-kusto-graphundazure-kusto-irql-graph