Microsoft Sentinel: Advanced Threat Hunting voor Overheidsorganisaties

Threat Hunter ! APT Found ! Suspicious i Proactive Hunt Active IOCs Found 3 Hunting Session Duration: 2h 15m | Queries: 47

In het huidige threat landscape is reactief security monitoring niet langer voldoende. Advanced Persistent Threats (APTs) blijven gemiddeld 287 dagen onopgemerkt in enterprise netwerken voordat ze worden gedetecteerd, volgens het Mandiant M-Trends 2024 rapport. Voor Nederlandse overheidsorganisaties die werken met gerubriceerde informatie en onder BIO-richtlijnen vallen, is proactive threat hunting essentieel om state-sponsored actors en sophisticated malware te detecteren voordat kritieke data wordt gecompromitteerd. Microsoft Sentinel, als cloud-native SIEM en SOAR platform, biedt krachtige threat hunting capabilities door ongelimiteerde data ingest, AI-powered behavioral analytics, en integratie met global threat intelligence. In dit artikel behandelen we enterprise-grade threat hunting methodologieën, geavanceerde KQL queries, MITRE ATT&CK mapping, en praktische hunting scenarios gebaseerd op real-world security operations bij Nederlandse overheidsdiensten.

Wat je leert

Deze uitgebreide gids behandelt enterprise Microsoft Sentinel threat hunting voor hoogbeveiligde overheidsomgevingen. Je leert threat hunting methodologieën (hypothesis-driven versus intelligence-led), geavanceerde KQL query technieken voor anomaly detection, MITRE ATT&CK framework mapping, behavioral analytics met UEBA, threat hunting workbooks, automatisering met Logic Apps, en integratie met Defender XDR en threat intelligence feeds. Inclusief 20+ productie-klare hunting queries en complete incident response playbooks conform BIO Norm 12.4 en NIS2.

Pro tip

Implementeer SCHEDULED hunting queries naast ad-hoc hunting! Veel SOC teams doen alleen handmatige threat hunting wanneer er al een incident is. Maak Sentinel Analytics Rules die jouw bewezen hunting queries AUTOMATISCH draaien elke 6-12 uur en alerts genereren bij verdachte patronen. Dit combineert proactieve hunting met reactieve detectie. Bij een ministerie detecteerden we hiermee een APT die credential dumping deed tussen 02:00-04:00 's nachts (buiten SOC uren) – onze scheduled hunting query voor LSASS process access triggerde automatisch en escaleerde naar de on-call engineer binnen 8 minuten, voordat lateral movement kon plaatsvinden!

Threat Hunting Fundamentals: Van Reactive naar Proactive Security

Van reactieve detectie naar proactieve jacht op aanvallers

Voor veel Nederlandse overheidsorganisaties is informatiebeveiliging nog sterk gericht op reactieve detectie. Het Security Operations Center (SOC) wacht totdat een vooraf gedefinieerde melding wordt gegenereerd, waarna een analist het incident onderzoekt. Deze aanpak werkt redelijk voor bekende dreigingen, maar schiet tekort tegen moderne, doelgerichte aanvallen. Aanvallers maken gebruik van maatwerk‑malware, legitieme beheerhulpmiddelen en technieken die bewust onder de drempel van klassieke detectieregels blijven. In rapportages zoals het Verizon Data Breach Investigations Report en Mandiant M‑Trends is consequent te zien dat geavanceerde aanvallen vaak maandenlang onopgemerkt blijven. Voor een overheid die werkt met gerubriceerde informatie, basisregistraties en maatschappelijke vitale processen is dat een onacceptabel risico.

Threat hunting verandert dit paradigma. In plaats van af te wachten tot een systeem een melding genereert, gaan ervaren analisten zelf actief op zoek naar afwijkend gedrag, subtiele signalen van misbruik en patronen die mogelijk wijzen op een aanvaller die zich al in de omgeving bevindt. Zij formuleren hypotheses over hoe een tegenstander zou kunnen opereren, combineren logbronnen en context, en gebruiken krachtige zoektaal zoals Kusto Query Language (KQL) om door enorme hoeveelheden data te navigeren. Waar klassieke detectieregels vooral gericht zijn op bekende indicatoren, richt threat hunting zich op gedrag: wie doet wat, op welk moment, met welke rechten en hoe wijkt dat af van het normale patroon.

Het verschil in uitkomst is groot. Een organisatie die uitsluitend leunt op reactieve detectie, ontdekt een deel van de aanvallen pas nadat schade zichtbaar wordt: systemen vallen uit, data is versleuteld of er duikt vertrouwelijke informatie op het dark web op. Een organisatie met een volwassen threat hunting‑programma ziet de eerste stappen van een aanval veel eerder: een beheeraccount dat zich op een ongebruikelijk tijdstip aanmeldt, een serviceaccount dat zich ineens naar veel meer servers verbindt dan normaal, of een werkstation dat op de achtergrond naar een zeldzame combinatie van IP‑adressen communiceert. Juist dat vroege signaal maakt het mogelijk om in te grijpen voordat de aanvaller domeinbrede controle krijgt of data kan exfiltreren.

Aansluiting op BIO en NIS2‑verplichtingen

Binnen de Nederlandse publieke sector is threat hunting geen luxe, maar een logisch vervolg op de eisen uit de Baseline Informatiebeveiliging Overheid (BIO) en de NIS2‑richtlijn. De BIO schrijft niet alleen voor dat gebeurtenissen worden gelogd, maar ook dat deze gebeurtenissen actief en doorlopend worden geanalyseerd. Paragrafen over logging, monitoring en incidentafhandeling veronderstellen feitelijk dat organisaties in staat zijn patronen, afwijkingen en mogelijke aanwijzingen van misbruik te herkennen in een grote hoeveelheid loggegevens. Threat hunting vormt de praktische invulling van die verplichting: het is de systematische, terugkerende analyse van log- en telemetriedata met als doel geavanceerde aanvallen vroegtijdig te ontdekken.

Ook NIS2 scherpt de verwachtingen verder aan. Essentiële en belangrijke entiteiten – zoals ministeries, uitvoeringsorganisaties, provincies en vitale ketenpartners – moeten aantoonbaar beschikken over capaciteiten voor detectie, analyse en respons. Een organisatie die bijvoorbeeld alleen een basis‑SIEM heeft ingericht zonder actief hunting‑programma, zal moeite hebben om tijdens een audit te onderbouwen dat zij geavanceerde aanvallen tijdig kan detecteren. Door threat hunting expliciet te positioneren als onderdeel van het Security Management System kan worden aangetoond dat aan deze zwaardere eisen wordt voldaan.

Groeipad naar volwassenheid

Niet iedere organisatie start met een volledig ingericht hunting‑team. In de praktijk doorlopen overheidsorganisaties vaak een groeipad. In de beginfase wordt Microsoft Sentinel vooral gebruikt als centrale plek waar logs samenkomen en waar een beperkte set standaardregels alerts genereert. Analisten onderzoeken die meldingen handmatig en passen waar nodig drempelwaarden aan. In de volgende fase gaan dezelfde analisten op vaste momenten in de week gericht zoeken naar afwijkingen, bijvoorbeeld rond beheerdersaccounts, externe VPN‑toegang of endpoints met verhoogd risico. De queries die in deze fase effectief blijken, worden opgeslagen en hergebruikt.

Vervolgens groeit de organisatie naar een situatie waarin threat hunting een structurele taak wordt met duidelijke doelstellingen, werkafspraken en documentatie. Hypotheses worden expliciet vastgelegd, inclusief de achterliggende dreigingsmodellen en de gebruikte MITRE ATT&CK‑technieken. Resultaten van hunts worden geanalyseerd om te bepalen welke nieuwe use‑cases als permanente detectieregel moeten worden geïmplementeerd. In de meest volwassen fase worden succesvolle hunting‑queries periodiek automatisch uitgevoerd en gekoppeld aan geautomatiseerde respons via playbooks. Daarmee ontstaat een geïntegreerde keten van detectie, triage en eerste tegenmaatregelen.

Rol van Microsoft Sentinel in de Nederlandse overheidscontext

Microsoft Sentinel is bij uitstek geschikt als fundament onder een dergelijk hunting‑programma. Het platform is cloud‑native, kan grote hoeveelheden logdata vanuit Microsoft 365, Azure, on‑premises omgevingen en andere cloudplatformen opnemen en biedt krachtige analysemogelijkheden. Voor Nederlandse overheidsorganisaties is het bovendien relevant dat data in Europese regio’s kan worden opgeslagen en dat encryptie standaard is ingeschakeld, zowel tijdens transport als in rust. Door Sentinel te koppelen aan diensten als Microsoft Defender voor Endpoint, Defender for Cloud Apps en Azure AD ontstaat een geïntegreerd beeld van identiteiten, apparaten, applicaties en infrastructuur.

Belangrijk is dat organisaties niet uitsluitend naar tooling kijken, maar vooral naar proces en mensen. Een klein, goed getraind hunting‑team dat structureel tijd krijgt om hypotheses uit te werken, kan met dezelfde tooling veel meer bereiken dan een overbelast SOC dat uitsluitend achter alerts aanloopt. Door kennis op te bouwen over eigen kroonjuwelen, kritieke processen en waarschijnlijke dreigingsactoren kunnen hunts gericht worden ingezet waar de impact het grootst is. Hierdoor wordt threat hunting een strategisch instrument dat direct bijdraagt aan de bescherming van de publieke taak en het vertrouwen van burgers in de digitale overheid.

Threat Hunting Methodologies: Hypothesis-Driven vs Intelligence-Led

Drie complementaire benaderingen voor gerichte dreigingsjacht

Een effectief threat hunting‑programma steunt niet op één enkele manier van zoeken, maar combineert verschillende methodieken die elkaar aanvullen. In de praktijk komen drie benaderingen steeds terug: hypothesegedreven hunting, intelligence‑gestuurde hunting en gedrag‑gebaseerde anomaly‑detectie. Deze methodieken gebruiken dezelfde onderliggende data in Microsoft Sentinel, maar starten vanuit een ander vertrekpunt en beantwoorden verschillende vragen. Door ze bewust naast elkaar in te zetten ontstaat een robuust raamwerk waarmee zowel bekende campagnes als volledig nieuwe aanvalspatronen kunnen worden ontdekt.

Bij hypothesegedreven hunting begint de analist met een duidelijke aanname over hoe een aanvaller zich zou kunnen gedragen in de eigen omgeving. Die aanname is gebaseerd op dreigingsmodellen, kennis van het landschap en ervaring met eerdere incidenten. Een voorbeeld is de veronderstelling dat een aanvaller die via phishing geldige inloggegevens van een medewerker heeft buitgemaakt, zich buiten reguliere kantooruren zal aanmelden vanaf een afwijkende locatie en daarna zal proberen hogere rechten te verkrijgen via misbruik van serviceaccounts of het dumpen van wachtwoorden uit het geheugen van een server. Vanuit zo’n hypothese wordt systematisch bepaald welke logbronnen nodig zijn, welke velden relevant zijn en welke query’s nodig zijn om het scenario te bevestigen of te weerleggen.

De kracht van deze methode is dat de hunter zelf de regie houdt en heel gericht naar sporen zoekt die passen bij een specifiek scenario. De uitkomst is niet alleen een lijst met verdachte gebeurtenissen, maar ook een beter begrip van hoe het aanvalspad er in de eigen infrastructuur uit zou zien. Wanneer een hypothese in de praktijk waardevol blijkt – bijvoorbeeld omdat er daadwerkelijk afwijkende aanmeldingen of verdachte processen worden gevonden – kan de bijbehorende KQL‑query worden verfijnd en uiteindelijk worden omgezet naar een permanente detectieregel in Sentinel. Op die manier groeit de detectie‑catalogus met concrete, bewezen use‑cases die goed aansluiten bij de risico’s van de organisatie.

Intelligence‑gestuurde hunting vertrekt vanuit externe dreigingsinformatie. Leveranciers, nationale CERT’s en onderzoeksorganisaties publiceren continu meldingen over nieuwe kwetsbaarheden, APT‑campagnes en misbruik van cloud‑diensten. In deze meldingen staan indicatoren van compromise zoals IP‑adressen, domeinnamen, bestands‑hashes en beschrijvingen van tactieken en technieken. Door deze informatie in Sentinel te importeren, kan een organisatie gericht zoeken naar sporen van die specifieke campagne in de eigen logdata. Gaat het bijvoorbeeld om een Russische statelijke actor die Europese overheden aanvalt via misbruik van VPN‑apparatuur, dan kan gericht worden nagegaan of er communicatie is geweest met de genoemde command‑and‑control infrastructuur, of dat er inlogpogingen zijn gedaan met kenmerken die in het advies worden genoemd.

Het voordeel van intelligence‑gestuurde hunting is dat het zoekgebied snel wordt verkleind tot wat in de actuele dreigingsinformatie als verdacht is aangemerkt. Tegelijkertijd is het belangrijk om zich niet blind te staren op individuele indicatoren. Professionele aanvallers wisselen IP‑adressen en domeinnamen regelmatig, waardoor de waarde van statische lijsten beperkt is. Daarom combineren ervaren hunters indicator‑gebaseerde zoekopdrachten altijd met het zoeken naar onderliggende tactieken en technieken, zoals ongebruikelijke VPN‑aanmeldingen, verhoogde mislukte logins of plotseling gebruik van beheerhulpmiddelen op servers.

De derde methode, gedrag‑gebaseerde hunting, richt zich op het vaststellen van afwijkingen ten opzichte van normaal gedrag in de eigen organisatie. Hiervoor wordt gebruikgemaakt van statistische analyse en machine‑learningfunctionaliteit, zoals de UEBA‑mogelijkheden van Microsoft Sentinel. Door over een langere periode vast te leggen hoe gebruikers, apparaten en toepassingen zich doorgaans gedragen – bijvoorbeeld welke data zij openen, wanneer zij inloggen en vanaf welke locaties – ontstaat een baseline. Afwijkingen van die baseline, zoals een medewerker die in één weekend honderden gigabytes aan gevoelige documenten downloadt of een serviceaccount dat zich ineens naar tientallen extra servers verbindt, vormen belangrijke startpunten voor een hunt.

In de praktijk worden deze drie methodieken vaak gecombineerd in één onderzoek. Een hypothese over credential‑dumping op werkstations van beheerders kan worden verrijkt met actuele dreigingsinformatie over tooling die door specifieke groepen wordt gebruikt en met gedragsprofielen van de betrokken accounts en systemen. Hierdoor ontstaat een veel rijker beeld dan wanneer uitsluitend naar losse indicatoren of simpelweg naar het aantal mislukte aanmeldingen wordt gekeken. De KQL‑query die bij zo’n onderzoek hoort, representeert uiteindelijk deze gecombineerde benadering: de query zoekt naar concrete procesnamen, kijkt naar specifieke loggebeurtenissen, maar weegt ook mee of gedrag afwijkt van wat in het verleden voor die gebruiker of dat systeem normaal was.

Een illustratief voorbeeld is het jagen op pogingen om het LSASS‑proces te benaderen op Windows‑systemen, met als doel inloggegevens uit het geheugen te halen. Dit scenario wordt in de bijbehorende KQL‑query technisch uitgewerkt door onder andere Sysmon‑gebeurtenissen, Defender‑telemetrie en bestandsgebeurtenissen te combineren. De methodiek daarachter is echter breder toepasbaar: start met een helder omschreven aanvalstechniek, bepaal welke sporen deze techniek in de beschikbare logbronnen achterlaat en vertaal dat naar reproduceerbare zoekopdrachten. Door deze werkwijze consequent toe te passen en de resultaten te documenteren, groeit stap voor stap een volwassen, herhaalbaar hunting‑programma dat aansluit op de bedreigingen waar de Nederlandse overheid in de praktijk mee te maken heeft.

Hunting Query (KQL):

kql
// Hunt for LSASS memory dumping attempts // MITRE ATT&CK T1003.001 - OS Credential Dumping: LSASS Memory let timeframe = 7d; // Hunt in past 7 days let lsassDumpTools = dynamic([ "mimikatz.exe", "procdump.exe", "procdump64.exe", "dumpert.exe", "sqldumper.exe", "rdrleakdiag.exe", "taskmgr.exe", "processhacker.exe", "procexp.exe", "nanodump.exe", "sajari.exe", "createdump.exe" ]); let suspiciousPaths = dynamic([ "\\users\\", // User temp dirs (not system paths) "\\temp\\", "\\downloads\\", "\\appdata\\local\\temp\\", "\\programdata\\" ]); // Method 1: Direct LSASS process access (Sysmon Event ID 10) let sysmonLsassAccess = SecurityEvent | where TimeGenerated > ago(timeframe) | where EventID == 10 // Sysmon ProcessAccess | extend TargetImage = tostring(EventData.TargetImage) | extend SourceImage = tostring(EventData.SourceImage) | extend GrantedAccess = tostring(EventData.GrantedAccess) | where TargetImage has_any ("lsass.exe") | where SourceImage !has_any ("system32", "SysWOW64") // Exclude legitimate system paths | where GrantedAccess has_any ("0x1410", "0x1010", "0x1438") // Memory read permissions | extend SuspiciousPath = iff(SourceImage has_any (suspiciousPaths), true, false) | extend KnownDumpTool = iff(SourceImage has_any (lsassDumpTools), true, false) | project TimeGenerated, Computer, SourceImage, TargetImage, GrantedAccess, Account, SuspiciousPath, KnownDumpTool; // Method 2: Defender for Endpoint detection let mdeCredentialDumping = DeviceProcessEvents | where TimeGenerated > ago(timeframe) | where ProcessCommandLine has_any ("lsass", "sekurlsa", "logonpasswords") | where ProcessCommandLine has_any ("dump", "minidump", "procdump", "-ma") | extend Severity = "High" | extend DetectionMethod = "Command Line Pattern" | project TimeGenerated, DeviceName, FileName, ProcessCommandLine, AccountName, Severity, DetectionMethod; // Method 3: File creation of LSASS dump files let lsassDumpFiles = DeviceFileEvents | where TimeGenerated > ago(timeframe) | where ActionType == "FileCreated" | where FileName has_any ("lsass", "lsass.dmp", "lsass.dump") | where FileName endswith ".dmp" or FileName endswith ".dump" or FileName endswith ".mdmp" | extend Severity = "Critical" | extend DetectionMethod = "Suspicious File Creation" | project TimeGenerated, DeviceName, FileName, FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine, Severity, DetectionMethod; // Combine all detection methods union sysmonLsassAccess, mdeCredentialDumping, lsassDumpFiles | where TimeGenerated > ago(timeframe) | summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), EventCount = count(), DetectionMethods = make_set(DetectionMethod), ProcessDetails = make_set(SourceImage), CommandLines = make_set(ProcessCommandLine) by DeviceName = coalesce(Computer, DeviceName), Account = coalesce(Account, AccountName) | extend RiskScore = case( EventCount >= 5, 100, // Multiple attempts = confirmed attack EventCount >= 3, 80, EventCount >= 2, 60, 40 // Single event ) | where RiskScore >= 60 // Filter low-confidence detections | order by RiskScore desc, LastSeen desc | project LastSeen, DeviceName, Account, EventCount, RiskScore, DetectionMethods, ProcessDetails, CommandLines, FirstSeen

Advanced KQL Query Techniques voor Threat Hunters

Waarom geoptimaliseerde KQL essentieel is voor succesvolle hunting

Threat hunting binnen Microsoft Sentinel betekent in de praktijk werken met enorme hoeveelheden loggegevens. Authenticatielogs, endpointtelemetrie, firewall‑informatie en applicatielogs produceren samen gemakkelijk miljarden records per maand. Zonder een zorgvuldige aanpak kunnen hunting‑query’s daardoor traag, duur en moeilijk te onderhouden worden. Voor Nederlandse overheidsorganisaties, waar budgetten en verwerkingssnelheid onder druk staan en waar tegelijkertijd hoge beschikbaarheidseisen gelden, is het cruciaal dat Kusto Query Language (KQL) niet alleen functioneel correcte, maar ook efficiënte zoekopdrachten oplevert.

Een eerste uitgangspunt bij elke hunting‑query is dat de tijdsperiode altijd zo vroeg mogelijk in de query wordt begrensd. Sentinel indexeert data primair op tijd, waardoor een filter op de kolom voor aanmaaktijd direct bepaalt welk deel van de tabel moet worden doorzocht. Wanneer een hunter pas laat in de query een tijdsfilter toevoegt, dwingt hij het platform om onnodig veel data te scannen. Door direct te beginnen met bijvoorbeeld een venster van zeven dagen, één dag of – bij incidentrespons – enkele uren, wordt de zoekopdracht aanzienlijk sneller en voorspelbaarder. Dit is niet alleen prettig tijdens interactief onderzoek, maar ook noodzakelijk wanneer dezelfde query later als geplande detectieregel wordt ingezet.

Ook de manier waarop op tekst wordt gezocht, heeft grote invloed op prestaties. Veel beginnende gebruikers grijpen naar operatoren zoals "contains" om een stukje tekst te vinden in een commandline of URL. Die operator doorzoekt de volledige string en is daarmee relatief kostbaar. In veel hunting‑scenario’s is een token‑gebaseerde benadering, waarbij gebruik wordt gemaakt van de operator "has" of diens hoofdlettergevoelige variant, voldoende en aanzienlijk efficiënter. Denk aan het zoeken naar het gebruik van een bepaald hulpmiddel of scriptnaam in de commandline van een proces. Door deze patronen consequent toe te passen, kunnen queries die aanvankelijk tientallen seconden nodig hadden, worden teruggebracht naar enkele seconden.

Een derde principe is dat filteren zo vroeg mogelijk en aggregeren zo laat mogelijk in de query plaatsvindt. Aggregaties zoals "summarize" zijn krachtige instrumenten om patronen op systeem‑ of gebruikersniveau te ontdekken, maar werken veel efficiënter als de invoer al is teruggebracht tot de gegevens die er echt toe doen. In plaats van een volledige tabel per computer samen te vatten en daarna records met een lage telling weg te gooien, is het daarom verstandig eerst in te zoomen op de relevante gebeurtenistypen, periode, accounts en systemen en pas vervolgens over die kleinere dataset te aggregeren. Dit principe maakt hunting‑queries niet alleen sneller, maar ook gemakkelijker te lezen en uit te leggen.

KQL biedt daarnaast de mogelijkheid om herbruikbare definities op te nemen via het "let"‑sleutelwoord. Voor threat hunters is dat bijzonder waardevol. Denk aan lijsten met verdachte IP‑adressen uit een threat‑intelligencefeed, sets van processen die vaak door aanvallers worden misbruikt of standaarddefinities van high‑risk logontypen. Door deze verzamelingen aan het begin van een query te declareren en vervolgens op meerdere plekken te gebruiken, wordt de logica van de query beter zichtbaar en kan een team sneller samenwerken en onderhoud plegen. Bovendien maakt dit het eenvoudig om op één centrale plek drempelwaarden en lijsten bij te werken zonder alle queries handmatig te hoeven aanpassen.

Wanneer de basisprincipes van filtering, tekstmatching en aggregatie goed worden toegepast, ontstaat ruimte om complexere scenario’s te modelleren, zoals laterale beweging binnen een domein. In zo’n scenario is het noodzakelijk om gebeurtenissen uit verschillende logbronnen met elkaar te correleren. Bijvoorbeeld: succesvolle netwerklogons met NTLM‑authenticatie op meerdere servers, gevolgd door het starten van beheerhulpmiddelen zoals PsExec of PowerShell‑remoting. Door met KQL stap voor stap een baseline op te bouwen van normaal gedrag, vervolgens afwijkende patronen te selecteren en deze daarna te koppelen aan verdachte procesuitvoering, ontstaat een meerlaagse zoekopdracht die de kern van een geavanceerde aanval blootlegt.

De multi‑stapquery die in deze sectie als voorbeeld wordt gegeven, illustreert hoe een hunter met KQL een compleet verhaal kan samenstellen: van de eerste, mogelijk afwijkende aanmelding tot en met de commando’s waarmee een aanvaller zich verder verspreidt. Door het gebruik van parameters voor tijdsperiode, duidelijke namen voor tussenresultaten en expliciete berekening van risicoscores is de query goed te begrijpen, eenvoudig aan te passen aan de eigen omgeving en geschikt om uiteindelijk als detectieregel met geautomatiseerde opvolging in te richten. Daarmee groeit KQL uit van een ad‑hoc hulpmiddel tot een structureel instrument voor het versterken van de digitale weerbaarheid van de organisatie.

Multi‑Stage Hunting Query:

kql
// Multi-stage lateral movement detection // Correlates authentication events with process execution // MITRE ATT&CK T1021 (Remote Services) + T1550.002 (Pass-the-Hash) let huntingWindow = 14d; let baselineWindow = 30d; // For behavioral baselining // Step 1: Build baseline of normal lateral movement patterns let normalLateralMovement = SecurityEvent | where TimeGenerated between (ago(baselineWindow) .. ago(huntingWindow)) | where EventID == 4624 // Successful logon | where LogonType == 3 // Network logon | where AccountType == "User" | where Account !endswith "$" // Exclude computer accounts | summarize NormalSourceComputers = make_set(IpAddress), NormalTargetComputers = make_set(Computer), BaselineLogonCount = count() by Account | extend NormalSourceCount = array_length(NormalSourceComputers) | extend NormalTargetCount = array_length(NormalTargetComputers); // Step 2: Detect unusual NTLM network logons in hunting window let suspiciousNetworkLogons = SecurityEvent | where TimeGenerated > ago(huntingWindow) | where EventID == 4624 | where LogonType == 3 // Network logon | where AuthenticationPackageName == "NTLM" // Pass-the-hash uses NTLM | where Account !endswith "$" | where Account !has "ANONYMOUS" // Filter out common service accounts (adjust for your environment) | where Account !has_any ("svc-", "sql-", "backup-") | extend SourceIP = IpAddress | extend TargetComputer = Computer | project TimeGenerated, Account, SourceIP, TargetComputer, WorkstationName, LogonProcessName, AuthenticationPackageName; // Step 3: Enrich with baseline comparison let anomalousLogons = suspiciousNetworkLogons | join kind=leftouter (normalLateralMovement) on Account | extend IsNewSource = iff(SourceIP !in (NormalSourceComputers), true, false) | extend IsNewTarget = iff(TargetComputer !in (NormalTargetComputers), true, false) | where IsNewSource == true or IsNewTarget == true // Anomaly detected | project TimeGenerated, Account, SourceIP, TargetComputer, IsNewSource, IsNewTarget, BaselineLogonCount; // Step 4: Correlate with suspicious process execution let suspiciousProcessExecution = DeviceProcessEvents | where TimeGenerated > ago(huntingWindow) | where FileName has_any ( "psexec.exe", "psexec64.exe", // PsExec "paexec.exe", // PsExec alternative "wmic.exe", // WMIC remote execution "wmiprvse.exe", // WMI provider host "powershell.exe" // PowerShell remoting ) | where ProcessCommandLine has_any ( "\\\\127.0.0.1", // Loopback (common in lateral movement) "-accepteula", // PsExec "Invoke-Command", // PS remoting "Enter-PSSession", "/node:", // WMIC remote "process call create" ) | extend TargetComputer = DeviceName | extend ExecutionTime = TimeGenerated | project ExecutionTime, TargetComputer, FileName, ProcessCommandLine, AccountName; // Step 5: Correlate logons with process execution (within 5 minute window) let correlatedEvents = anomalousLogons | join kind=inner ( suspiciousProcessExecution ) on TargetComputer | where ExecutionTime between (TimeGenerated .. (TimeGenerated + 5m)) | project LogonTime = TimeGenerated, ExecutionTime, Account, SourceIP, TargetComputer, ProcessExecuted = FileName, CommandLine = ProcessCommandLine, IsNewSource, IsNewTarget, BaselineLogonCount; // Step 6: Calculate risk score and prioritize correlatedEvents | extend RiskScore = 40 + // Base score for correlation iff(IsNewSource, 25, 0) + // New source IP iff(IsNewTarget, 25, 0) + // New target computer iff(ProcessExecuted has_any ("psexec", "wmic"), 20, 0) + // High-risk tool iff(BaselineLogonCount < 10, 15, 0) // Infrequent account usage | where RiskScore >= 70 // High-confidence detections only | summarize FirstLogon = min(LogonTime), LastExecution = max(ExecutionTime), TargetComputers = make_set(TargetComputer), ProcessesExecuted = make_set(ProcessExecuted), CommandLines = make_set(CommandLine), EventCount = count(), MaxRiskScore = max(RiskScore) by Account, SourceIP | extend TotalTargets = array_length(TargetComputers) | where TotalTargets >= 2 // Lateral movement to multiple targets | order by MaxRiskScore desc, TotalTargets desc | project Account, SourceIP, TotalTargets, TargetComputers, FirstLogon, LastExecution, ProcessesExecuted, MaxRiskScore, EventCount

User & Entity Behavioral Analytics (UEBA): ML-Powered Anomaly Detection

Gedragsanalyse als extra zintuig voor het SOC

Zelfs met de beste detectieregels blijft het lastig om subtiele of langzaam ontwikkelende dreigingen op tijd te herkennen. Aanvallers die zich langdurig in een omgeving schuilhouden, passen hun gedrag aan om onder de radar te blijven. Medewerkers met kwade bedoelingen kennen de procedures en weten vaak precies welke handelingen een alarm zouden veroorzaken. User & Entity Behavioral Analytics (UEBA) in Microsoft Sentinel voegt een extra laag toe aan de beveiliging door niet alleen naar losse gebeurtenissen te kijken, maar naar patronen in het gedrag van gebruikers, apparaten en andere entiteiten over een langere periode. In plaats van vooraf te definiëren wat verdacht is, laat UEBA machine‑learningalgoritmen bepalen wat normaal is en markeert vervolgens afwijkingen.

De kracht van deze aanpak zit in het combineren van context uit verschillende bronnen. Aanmeldgegevens uit Entra ID (voorheen Azure AD), wijzigingslogboeken uit Azure‑ en M365‑omgevingen, activiteiten in SharePoint en Exchange, beveiligingsgebeurtenissen van Windows‑servers, firewall‑logs en gegevens uit externe systemen worden samengebracht in één gedragsprofiel. Voor iedere gebruiker wordt bijvoorbeeld vastgelegd op welke tijden doorgaans wordt gewerkt, welke toepassingen en data regelmatig worden benaderd en vanaf welke locaties en apparaten dat gebeurt. Voor apparaten wordt bijgehouden welke processen normaal draaien, hoe netwerkverkeer zich over de dag verdeelt en hoe vaak er beheerhandelingen plaatsvinden.

Op basis van deze profielen berekent Sentinel risicoscores en genereert het zogenoemde "insights" wanneer gedrag significant afwijkt van het patroon. Dat kan gaan om een gebruiker die ineens midden in de nacht grote hoeveelheden bestanden downloadt, een apparaat dat plotseling verbinding maakt met een land waar de organisatie normaal geen activiteiten heeft, of een serviceaccount dat opeens veel vaker wordt gebruikt dan in de afgelopen maanden. Belangrijk is dat deze signalen niet geïsoleerd worden beschouwd, maar in samenhang met andere indicatoren. Een eenmalige late aanmelding is op zichzelf wellicht onschuldig, maar in combinatie met een onbekend apparaat en verhoogde data‑activiteit kan het een sterke aanwijzing zijn voor misbruik.

Voor SOC‑teams in de publieke sector biedt UEBA hiermee twee grote voordelen. Ten eerste helpt het om prioriteit te geven aan meldingen. In plaats van een lange lijst met generieke alerts, kunnen analisten focussen op entiteiten met een verhoogde risicoscore. Ten tweede maakt gedragsanalyse het mogelijk dreigingen te detecteren waarvoor geen duidelijke handtekening bestaat. Een medewerker die voorbereidingen treft om gevoelige dossiers mee te nemen naar een nieuwe werkgever, gebruikt waarschijnlijk geen malware of bekende aanvalstools. Het gedrag – het opzoeken van documenten buiten de eigen taak, het veelvuldig downloaden van bestanden in korte tijd en het gebruik van niet‑geautoriseerde cloudopslag – wijkt echter wel af van het normale patroon en kan daarom toch worden opgemerkt.

Een typisch insider‑threatscenario laat zien hoe dit in de praktijk werkt. In de eerste fase verandert het zoekgedrag van de medewerker: er worden steeds meer dossiers geraadpleegd buiten de eigen afdeling of het eigen project. Daarna neemt het aantal downloads toe en volgt wellicht toegang tot bestanden die hoger geclassificeerd zijn dan voor de functie noodzakelijk is. Deze activiteiten vinden vaak plaats op momenten dat er weinig collega’s online zijn, bijvoorbeeld in de avonduren of in het weekend. UEBA ziet dat het gedrag afwijkt van zowel het historische patroon van deze gebruiker als van het gedrag van collega’s in vergelijkbare functies. De resulterende insights geven het SOC aanleiding om gerichte vragen te stellen, het gesprek met de leidinggevende aan te gaan of aanvullende technische maatregelen te nemen.

Gedragsanalyse staat niet op zichzelf, maar wordt idealiter geïntegreerd met de overige detectie‑ en responsprocessen. In Sentinel kunnen UEBA‑insights worden gekoppeld aan incidenten, risicoscores kunnen worden meegewogen in geautomatiseerde beslissingen en resultaten van hunting‑query’s kunnen worden verrijkt met informatie over hoe bijzonder het gedrag van een betrokken gebruiker of apparaat is. Zo kan een query die mogelijke data‑exfiltratie detecteert, bijvoorbeeld prioriteit geven aan resultaten waarbij de betrokken gebruiker ook een sterke stijging in UEBA‑risico laat zien. Dit helpt SOC‑analisten om hun tijd te besteden aan de casussen waar de kans op daadwerkelijke schade het grootst is.

Voor Nederlandse overheidsorganisaties, waar privacy en proportionaliteit zwaar wegen, is het belangrijk om UEBA zorgvuldig in te richten. Transparantie over doel, reikwijdte en bewaartermijnen, betrokkenheid van de Functionaris Gegevensbescherming en duidelijke afspraken met ondernemingsraden helpen om draagvlak te creëren. Wanneer deze randvoorwaarden goed zijn ingebed, vormt UEBA een krachtig aanvullend instrument om misbruik van accounts, ongeoorloofde toegang tot gerubriceerde informatie en langzaam voortschrijdende aanvallen eerder te signaleren, zonder dat medewerkers continu onder een vergrootglas liggen.

UEBA Detection Query (KQL):

kql
// Insider threat detection via UEBA anomaly scoring // Combines multiple behavioral signals for high-fidelity detection let investigationPeriod = 30d; // Get all UEBA anomalies for the investigation period let uebaAnomalies = BehaviorAnalytics | where TimeGenerated > ago(investigationPeriod) | where ActivityType in ( "Anomalous file access", "Anomalous download", "Unusual data access", "Unusual logon time", "Access from unusual location", "Unusual peer group behavior" ) | extend AnomalyScore = InvestigationPriority // 0-100 scale | extend UserAccount = UserPrincipalName; // Correlate with file access patterns from Office 365 let fileAccessPatterns = OfficeActivity | where TimeGenerated > ago(investigationPeriod) | where Operation in ("FileDownloaded", "FileAccessed", "FileShared") | summarize TotalFileAccess = count(), UniqueFilesAccessed = dcount(OfficeObjectId), UniqueSitesAccessed = dcount(SiteUrl), TotalDownloads = countif(Operation == "FileDownloaded"), ExternalShares = countif(Operation == "FileShared" and TargetUserOrGroupType == "Guest") by UserAccount = UserId, bin(TimeGenerated, 1d) | summarize DailyAvgFileAccess = avg(TotalFileAccess), MaxDailyFileAccess = max(TotalFileAccess), DailyAvgDownloads = avg(TotalDownloads), MaxDailyDownloads = max(TotalDownloads), TotalExternalShares = sum(ExternalShares), UniqueSitesAccessed = sum(UniqueSitesAccessed) by UserAccount; // Identify users with concerning file access patterns let suspiciousFileActivity = fileAccessPatterns | where MaxDailyDownloads > (DailyAvgDownloads * 5) // 5x spike or TotalExternalShares > 10 // Significant external sharing or UniqueSitesAccessed > 50 // Access to many different sites | extend FileActivityRisk = iff(MaxDailyDownloads > DailyAvgDownloads * 10, 40, 0) + iff(TotalExternalShares > 20, 30, iff(TotalExternalShares > 10, 15, 0)) + iff(UniqueSitesAccessed > 100, 20, iff(UniqueSitesAccessed > 50, 10, 0)) | where FileActivityRisk > 30; // Check for unusual authentication patterns let authenticationAnomalies = SigninLogs | where TimeGenerated > ago(investigationPeriod) | where ResultType == "0" // Successful | extend Hour = hourofday(TimeGenerated) | extend IsWeekend = dayofweek(TimeGenerated) in (0d, 6d) // Sunday=0, Saturday=6 | extend IsOffHours = Hour < 7 or Hour > 19 | summarize TotalSignIns = count(), OffHoursSignIns = countif(IsOffHours), WeekendSignIns = countif(IsWeekend), UniqueLocations = dcount(Location), UniqueDevices = dcount(DeviceDetail.deviceId), UnknownDeviceSignIns = countif(DeviceDetail.isCompliant == false or DeviceDetail.deviceId == "") by UserPrincipalName | extend AuthAnomalyRisk = iff(OffHoursSignIns > 10, 25, 0) + iff(WeekendSignIns > 5, 20, 0) + iff(UniqueLocations > 5, 15, 0) + iff(UnknownDeviceSignIns > 3, 30, 0) // Personal devices? | where AuthAnomalyRisk > 30; // Aggregate all risk indicators per user let insiderThreatRiskScores = uebaAnomalies | summarize UEBAAnomalyCount = count(), MaxUEBAAnomalyScore = max(AnomalyScore), AvgUEBAAnomalyScore = avg(AnomalyScore), AnomalyTypes = make_set(ActivityType) by UserAccount | join kind=fullouter (suspiciousFileActivity) on $left.UserAccount == $right.UserAccount | join kind=fullouter (authenticationAnomalies) on $left.UserAccount == $right.UserPrincipalName | extend UserAccount = coalesce(UserAccount, UserAccount1, UserPrincipalName) | project-away UserAccount1, UserPrincipalName | extend TotalRiskScore = coalesce(MaxUEBAAnomalyScore, 0) + coalesce(FileActivityRisk, 0) + coalesce(AuthAnomalyRisk, 0) | where TotalRiskScore >= 80 // High-risk threshold | project UserAccount, TotalRiskScore, UEBAAnomalyCount, MaxUEBAAnomalyScore, AnomalyTypes, FileActivityRisk, MaxDailyDownloads, TotalExternalShares, AuthAnomalyRisk, OffHoursSignIns, UniqueLocations | order by TotalRiskScore desc; // Enrich with user profile data from Azure AD insiderThreatRiskScores | join kind=leftouter ( IdentityInfo | where TimeGenerated > ago(7d) | summarize arg_max(TimeGenerated, *) by AccountUPN | project UserAccount = AccountUPN, DisplayName = AccountDisplayName, Department, JobTitle, Manager ) on UserAccount | project UserAccount, DisplayName, Department, JobTitle, TotalRiskScore, RiskIndicators = pack( "UEBA_Anomalies", UEBAAnomalyCount, "Max_UEBA_Score", MaxUEBAAnomalyScore, "File_Activity_Risk", FileActivityRisk, "Auth_Anomaly_Risk", AuthAnomalyRisk, "Max_Daily_Downloads", MaxDailyDownloads, "External_Shares", TotalExternalShares, "Off_Hours_SignIns", OffHoursSignIns, "Unique_Locations", UniqueLocations ), AnomalyTypes | order by TotalRiskScore desc

MITRE ATT&CK Framework Integration: Coverage & Gap Analysis

Een gemeenschappelijke taal voor aanvallers en verdedigers

Waar traditionele beveiligingsdocumentatie vaak blijft steken in abstracte termen als "malware", "hackers" en "ongeautoriseerde toegang", biedt het MITRE ATT&CK‑framework een precieze, gedeelde woordenschat om het gedrag van aanvallers te beschrijven. Het framework is opgebouwd uit tactieken – de doelen die een aanvaller probeert te bereiken, zoals het verkrijgen van toegang of het verhogen van rechten – en technieken en subtechnieken, die concreet beschrijven hoe dat doel in de praktijk wordt gerealiseerd. Door deze structuur ontstaat een soort kaart van het aanvalspad, waarop voor iedere stap herkenbare patronen zijn vastgelegd. Voor organisaties in de publieke sector is dit bijzonder waardevol, omdat het gesprek tussen CISO, SOC‑analisten, leveranciers en auditors daarmee veel concreter wordt.

Microsoft Sentinel sluit nauw aan op dit framework. Iedere detectieregel kan worden gekoppeld aan één of meerdere ATT&CK‑technieken, en in de portal is een dashboard beschikbaar dat laat zien voor welke tactieken en technieken al dekking bestaat. In plaats van een ongestructureerde lijst met tientallen of honderden regels, ontstaat zo een overzicht van welke onderdelen van de aanvalsketen goed zijn afgedekt en waar nog blinde vlekken zitten. Dit maakt het mogelijk om investeringen in tijd en middelen te koppelen aan een duidelijk risicobeeld: als blijkt dat er veel regels zijn voor het detecteren van initiële toegang, maar nauwelijks voor laterale beweging en data‑exfiltratie, ligt het voor de hand om nieuwe hunting‑use‑cases juist daar te ontwikkelen.

Een belangrijk inzicht dat ATT&CK biedt, is dat dezelfde techniek vaak op meerdere manieren kan worden ingezet en in verschillende fasen van een aanval kan terugkomen. Neem bijvoorbeeld het stelen van inloggegevens uit een Active Directory‑omgeving. Het onderliggende doel – het verkrijgen van toegang tot accounts om zich lateraal te verplaatsen of om systemen over te nemen – valt onder de tactiek "Credential Access". De concrete manieren waarop dit gebeurt, variëren van het uitlezen van wachtwoordhashes in het geheugen tot het kopiëren van de volledige directorydatabase. Door deze varianten als subtechnieken te modelleren, wordt duidelijk welke sporen in logdata zijn te verwachten en welke detectieregels daarvoor nodig zijn.

Sentinel kan de relatie tussen detectieregels en ATT&CK‑technieken automatisch inzichtelijk maken, maar het is aan de organisatie om die informatie te gebruiken in een systematische coverage‑analyse. Dat begint met een inventarisatie van alle actieve regels en hun bijbehorende tactieken en technieken. Vervolgens wordt per tactiek berekend welk percentage van de relevante technieken is afgedekt door ten minste één regel. Het resultaat is een heatmap: tactieken met veel dekking kleuren groen, tactieken met weinig of geen dekking vallen op als oranje of rood. Op basis daarvan kan een CISO prioriteiten stellen, bijvoorbeeld door te besluiten dat binnen zes maanden voor alle technieken binnen "Lateral Movement" en "Exfiltration" minimaal één robuuste detectieregel beschikbaar moet zijn.

Het ontwikkelen van nieuwe hunting‑scenario’s wordt in deze aanpak gedreven door de gevonden gaten. Stel dat uit de analyse blijkt dat er geen enkele regel is die specifiek gericht is op pogingen om de Active Directory‑database (ntds.dit) veilig te stellen voor later misbruik, terwijl dit in het ATT&CK‑framework als een kritieke subtechniek wordt aangemerkt. Dan is dat een duidelijke aanleiding om een gericht hunt‑scenario te ontwerpen. Daarbij wordt eerst de techniek zelf bestudeerd: welke tools worden doorgaans gebruikt, welke systeemonderdelen zijn erbij betrokken, welke logbronnen kunnen sporen bevatten en hoe ziet normaal beheer eruit in vergelijking met malafide activiteiten.

De KQL‑query die in deze sectie wordt gepresenteerd, is het resultaat van zo’n ATT&CK‑gedreven ontwerp. Zij zoekt naar directe toegang tot de directorydatabase, naar het gebruik van hulpprogramma’s voor Volume Shadow Copy en naar verdachte activiteiten op domeincontrollers rond het LSASS‑proces. Door deze verschillende signalen samen te brengen en een risicoscore te berekenen, kan een organisatie met hoge betrouwbaarheid potentieel catastrofale acties detecteren. Tegelijkertijd wordt de relatie met ATT&CK expliciet vastgelegd, zodat bij een volgende coverage‑analyse direct zichtbaar is dat deze techniek inmiddels wordt afgedekt.

Voor Nederlandse overheidsorganisaties biedt deze manier van werken twee belangrijke voordelen. Ten eerste wordt de dialoog met toezichthouders en auditors concreter: in plaats van generiek te stellen dat "passende maatregelen" zijn genomen, kan worden aangetoond voor welke internationaal erkende aanvalstechnieken detectie en respons zijn ingericht. Ten tweede helpt het om kennisdeling te structureren. Nieuwe use‑cases kunnen worden beschreven in termen van tactieken en technieken en eenvoudig worden uitgewisseld tussen ministeries, uitvoeringsorganisaties en andere publieke partijen, zonder dat men elkaars interne architectuur tot in detail hoeft te kennen. Zo groeit stap voor stap een gedeeld begrippenkader en een gezamenlijke verdedigingslinie tegen geavanceerde digitale dreigingen.

Hunting Query voor T1003.003:

kql
// Hunt for Active Directory database dumping (NTDS extraction) // MITRE ATT&CK T1003.003 - NTDS let huntingPeriod = 30d; // Method 1: Direct ntds.dit file access let ntdsFileAccess = DeviceFileEvents | where TimeGenerated > ago(huntingPeriod) | where FolderPath has_any ( "\\ntds.dit", "\\Windows\\NTDS\\", "\\System Volume Information\\" // VSS snapshots ) | where ActionType in ("FileCreated", "FileRenamed", "FileCopied") | extend Severity = "Critical" | extend DetectionMethod = "NTDS File Access" | project TimeGenerated, DeviceName, FileName, FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName, Severity; // Method 2: Use of ntdsutil or vssadmin (Volume Shadow Copy) let ntdsDumpTools = DeviceProcessEvents | where TimeGenerated > ago(huntingPeriod) | where FileName has_any ( "ntdsutil.exe", "vssadmin.exe", "wmic.exe", "diskshadow.exe", "esentutl.exe" // ESE database utility ) | where ProcessCommandLine has_any ( "create full", // ntdsutil: create full backup "ifm", // ntdsutil: install from media "create shadow", // vssadmin: create VSS "shadowcopy", // WMIC shadowcopy "ntds.dit", // Direct reference "system.hiv" // SYSTEM registry hive (needed for decryption) ) | extend Severity = "Critical" | extend DetectionMethod = "NTDS Dump Tool Execution" | project TimeGenerated, DeviceName, FileName, ProcessCommandLine, AccountName, InitiatingProcessFileName, Severity; // Method 3: Detection via Windows Event Logs (DC only) let dcAuditEvents = SecurityEvent | where TimeGenerated > ago(huntingPeriod) | where Computer has "DC" // Domain Controllers only | where EventID in ( 4662, // Operation performed on Active Directory object 5136 // Directory service object was modified ) | where ObjectName has "ntds.dit" or AccessMask has "0x100" // READ_CONTROL | extend Severity = "High" | extend DetectionMethod = "AD Audit Event" | project TimeGenerated, Computer, Account, EventID, ObjectName, AccessMask, Severity; // Method 4: Suspicious process accessing LSASS on Domain Controller let dcLsassAccess = DeviceProcessEvents | where TimeGenerated > ago(huntingPeriod) | where DeviceName has "DC" // Domain Controllers | where ProcessCommandLine has "lsass.exe" or FileName == "lsass.exe" | where InitiatingProcessFileName !in ( "services.exe", "wininit.exe", "csrss.exe" // Legitimate parent processes ) | extend Severity = "High" | extend DetectionMethod = "DC LSASS Access" | project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, AccountName, Severity; // Combine all detection methods union ntdsFileAccess, ntdsDumpTools, dcAuditEvents, dcLsassAccess | summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), EventCount = count(), DetectionMethods = make_set(DetectionMethod), Devices = make_set(coalesce(DeviceName, Computer)), Processes = make_set(FileName), CommandLines = make_set(ProcessCommandLine), MaxSeverity = max(Severity) by Account = coalesce(AccountName, Account) | extend RiskScore = case( array_length(DetectionMethods) >= 3, 100, // Multiple methods = confirmed MaxSeverity == "Critical", 90, EventCount >= 5, 80, 70 ) | where RiskScore >= 70 | extend ATT&CK_Technique = "T1003.003 - NTDS" | extend ATT&CK_Tactic = "Credential Access" | project LastSeen, Account, Devices, EventCount, RiskScore, DetectionMethods, Processes, MaxSeverity, "ATT&CK_Technique", "ATT&CK_Tactic" | order by RiskScore desc

Hunting Automation: Van Ad-Hoc Query naar Detection Rule

Van eenmalige zoektocht naar blijvende bewaking

Veel SOC‑teams herkennen het patroon: een analist ontwikkelt in de hectiek van een incident een slimme KQL‑query waarmee een dreiging snel zichtbaar wordt gemaakt. Die query blijft vervolgens in een persoonlijke map staan, wordt incidenteel nog eens gebruikt, maar verdwijnt uiteindelijk naar de achtergrond. De organisatie profiteert dan slechts tijdelijk van de geïnvesteerde tijd en kennis. Om echt waarde te halen uit threat hunting is het noodzakelijk om succesvolle zoekopdrachten te verheffen tot structurele detectie‑ en responsmechanismen. Microsoft Sentinel biedt hiervoor een duidelijke "hunting‑naar‑detectie"‑keten waarmee een eenmalige analyse kan uitgroeien tot een geautomatiseerde verdedigingslijn.

Het proces begint altijd bij handmatig onderzoek. In deze fase werkt de hunter met ruwe data, probeert verschillende invalshoeken uit en scherpt de query stap voor stap aan. Daarbij wordt gekeken naar de balans tussen compleetheid en ruis: een query die theoretisch alle gevallen vindt maar dagelijks honderden valse positieven oplevert, is in de praktijk niet bruikbaar. Door testperioden te kiezen waarin bekende incidenten hebben plaatsgevonden, kan worden gevalideerd of de query die casussen daadwerkelijk terugvindt. Tegelijkertijd wordt gecontroleerd of normale beheeractiviteiten ten onrechte als verdacht worden aangemerkt. Deze iteratieve verfijning is essentieel voordat automatisering in beeld komt.

Wanneer de query in de praktijk effectief blijkt, volgt een optimalisatiefase. Hierin wordt de zoekopdracht herschreven met oog voor prestaties en onderhoudbaarheid. Onnodige kolommen worden verwijderd, filters worden naar voren gehaald en drempelwaarden worden parametriseerbaar gemaakt. Ook wordt de query rijkelijk voorzien van commentaar, zodat later duidelijk is welke aannames zijn gedaan, welke MITRE ATT&CK‑technieken worden afgedekt en hoe de query is getest. Dit is het moment om na te denken over hergebruik: kan dezelfde logica bijvoorbeeld zowel voor servers als werkplekken worden toegepast, en zijn er varianten nodig voor verschillende typen accounts of omgevingen (productie versus test).

Vervolgens wordt de query omgezet naar een geplande detectieregel binnen Sentinel. In de configuratie wordt vastgelegd hoe vaak de query moet draaien, over welke terugkijkperiode zij data mag analyseren en vanaf welke drempel er daadwerkelijk een alert of incident moet worden aangemaakt. Voor dreigingen die zich snel ontwikkelen, zoals credential‑dumping op een domeincontroller, ligt een hoge frequentie met een relatief korte terugkijkperiode voor de hand. Voor langlopende patronen, zoals het langzaam wegsluizen van data, zijn minder frequente runs met een grotere tijdspanne logischer. Door alert‑groepering in te richten, kan worden voorkomen dat tientallen gelijksoortige gebeurtenissen leiden tot een overvloed aan incidenten; in plaats daarvan worden ze samengevoegd tot één dossier.

Een volwassen aanpak stopt niet bij detectie. De volgende stap is het definiëren van geautomatiseerde responsacties die passen bij de ernst van de dreiging en de risicobereidheid van de organisatie. Met behulp van Logic Apps kunnen playbooks worden ingericht die direct na het ontstaan van een incident worden uitgevoerd. Denk aan het automatisch verrijken van een melding met informatie over betrokken gebruikers, apparaten en eerdere incidenten, het tijdelijk blokkeren van een account met een verhoogde UEBA‑risicoscore of het isoleren van een endpoint dat vermoedelijk is gecompromitteerd. Daarbij is het verstandig om onderscheid te maken tussen volledig geautomatiseerde acties en stappen die eerst een expliciete goedkeuring van een analist vereisen, zeker in omgevingen met kritieke processen.

Het geautomatiseerde playbook dat in deze sectie wordt beschreven, laat zien hoe ver zo’n keten kan gaan. Op basis van een incident rond credential‑dumping worden betrokken accounts en apparaten opgehaald, wordt de risico‑inschatting uit Identity Protection gebruikt om te beslissen of accounts direct moeten worden uitgeschakeld en worden apparaten via Defender for Endpoint geïsoleerd en gescand. Tegelijkertijd wordt een ticket aangemaakt in een IT‑servicemanagementsysteem en ontvangt het SOC een gedetailleerde melding in Microsoft Teams. Tot slot wordt in Sentinel zelf een commentaar toegevoegd waarin alle automatische stappen worden gedocumenteerd. Zo heeft iedere analist die het incident later opent direct inzicht in wat er al is gebeurd en welke vervolgacties nog nodig zijn.

Het laatste, vaak vergeten onderdeel van de pipeline is continue tuning. Nadat een regel enige tijd in productie heeft gedraaid, moet worden geëvalueerd hoeveel incidenten zijn ontstaan, hoeveel daarvan daadwerkelijk relevant waren en of aanvallers nieuwe varianten van dezelfde techniek zijn gaan gebruiken. Op basis van die inzichten worden drempelwaarden aangepast, extra filters toegevoegd of juist verwijderd en waar nodig aanvullende use‑cases ontwikkeld. Dit is geen eenmalig project, maar een doorlopend proces dat idealiter wordt vastgelegd in reguliere verbetercycli. Door deze discipline vol te houden verandert threat hunting van een serie losse onderzoeksacties in een duurzame, lerende beveiligingsfunctie die de weerbaarheid van de organisatie jaar op jaar versterkt.

Automatiseringsvoorbeeld: LSASS‑hunting als detectieregel en playbook

json
{ "definition": { "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", "triggers": { "Microsoft_Sentinel_incident": { "type": "ApiConnectionWebhook", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuresentinel']['connectionId']" } }, "body": { "callback_url": "@{listCallbackUrl()}" }, "path": "/incident-creation" } } }, "actions": { "Get_Incident": { "runAfter": {}, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuresentinel']['connectionId']" } }, "method": "get", "path": "/Incidents/@{triggerBody()?['object']?['id']}" } }, "Get_Entities": { "runAfter": { "Get_Incident": ["Succeeded"] }, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuresentinel']['connectionId']" } }, "method": "post", "path": "/Entities/GetIncidentEntities", "body": { "incidentId": "@{body('Get_Incident')?['name']}" } } }, "For_Each_Account": { "foreach": "@body('Get_Entities')?['Accounts']", "actions": { "Get_User_Risk": { "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuread']['connectionId']" } }, "method": "get", "path": "/v1.0/identityProtection/riskyUsers/@{items('For_Each_Account')?['AadUserId']}" } }, "Condition_High_Risk_User": { "type": "If", "expression": { "or": [ { "equals": [ "@body('Get_User_Risk')?['riskLevel']", "high" ] }, { "equals": [ "@body('Get_User_Risk')?['riskLevel']", "medium" ] } ] }, "actions": { "Disable_Account": { "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuread']['connectionId']" } }, "method": "patch", "path": "/v1.0/users/@{items('For_Each_Account')?['AadUserId']}", "body": { "accountEnabled": false } }, "description": "Disable compromised account immediately" }, "Revoke_Sessions": { "runAfter": { "Disable_Account": ["Succeeded"] }, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuread']['connectionId']" } }, "method": "post", "path": "/v1.0/users/@{items('For_Each_Account')?['AadUserId']}/revokeSignInSessions" }, "description": "Revoke all active sessions and refresh tokens" } } } }, "runAfter": { "Get_Entities": ["Succeeded"] }, "type": "Foreach" }, "For_Each_Device": { "foreach": "@body('Get_Entities')?['Hosts']", "actions": { "Isolate_Device": { "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['wdatp']['connectionId']" } }, "method": "post", "path": "/api/machines/@{items('For_Each_Device')?['MdatpDeviceId']}/isolate", "body": { "Comment": "Automated isolation - LSASS credential dumping detected", "IsolationType": "Full" } }, "description": "Isolate device via Defender for Endpoint" }, "Run_AV_Scan": { "runAfter": { "Isolate_Device": ["Succeeded"] }, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['wdatp']['connectionId']" } }, "method": "post", "path": "/api/machines/@{items('For_Each_Device')?['MdatpDeviceId']}/runAntiVirusScan", "body": { "Comment": "Full AV scan after credential dumping detection", "ScanType": "Full" } } }, "Collect_Investigation_Package": { "runAfter": { "Run_AV_Scan": ["Succeeded"] }, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['wdatp']['connectionId']" } }, "method": "post", "path": "/api/machines/@{items('For_Each_Device')?['MdatpDeviceId']}/collectInvestigationPackage", "body": { "Comment": "Collect forensics for LSASS dumping incident" } }, "description": "Collect full investigation package for forensics" } }, "runAfter": { "For_Each_Account": ["Succeeded"] }, "type": "Foreach" }, "Create_ServiceNow_Ticket": { "runAfter": { "For_Each_Device": ["Succeeded"] }, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['servicenow']['connectionId']" } }, "method": "post", "path": "/api/now/table/incident", "body": { "short_description": "[P1] Credential Dumping Detected - @{body('Get_Incident')?['title']}", "description": "Automated detection of LSASS memory dumping attempt.\n\nIncident ID: @{body('Get_Incident')?['name']}\nSeverity: High\nMITRE ATT&CK: T1003.001\n\nAffected accounts: @{length(body('Get_Entities')?['Accounts'])}\nAffected devices: @{length(body('Get_Entities')?['Hosts'])}\n\nAutomated actions taken:\n- Disabled compromised accounts\n- Revoked active sessions\n- Isolated affected devices\n- Initiated full AV scans\n- Collected forensic investigation packages\n\nNext steps: SOC analyst to review Sentinel incident and investigate root cause.", "priority": "1", "category": "Security Incident", "assignment_group": "Security Operations Center" } } }, "Send_Teams_Notification": { "runAfter": { "Create_ServiceNow_Ticket": ["Succeeded"] }, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['teams']['connectionId']" } }, "method": "post", "path": "/v3/beta/teams/@{parameters('SOC_Team_ID')}/channels/@{parameters('Incidents_Channel_ID')}/messages", "body": { "rootMessage": { "body": { "contentType": "html", "content": "<h2>🚨 High Severity Security Incident</h2><p><strong>LSASS Credential Dumping Detected</strong></p><p>Incident: <a href='@{body('Get_Incident')?['incidentUrl']}'>@{body('Get_Incident')?['title']}</a></p><p>Severity: <span style='color: red;'><strong>HIGH</strong></span><br/>MITRE ATT&CK: T1003.001<br/>Affected Accounts: @{length(body('Get_Entities')?['Accounts'])}<br/>Affected Devices: @{length(body('Get_Entities')?['Hosts'])}</p><p><strong>Automated Response Actions:</strong><br/>✅ Accounts disabled<br/>✅ Sessions revoked<br/>✅ Devices isolated<br/>✅ AV scans initiated<br/>✅ Forensics collected<br/>✅ ServiceNow ticket created</p><p><strong>Action Required:</strong> SOC analyst review and root cause analysis</p>" } } } } }, "Update_Incident_Comment": { "runAfter": { "Send_Teams_Notification": ["Succeeded"] }, "type": "ApiConnection", "inputs": { "host": { "connection": { "name": "@parameters('$connections')['azuresentinel']['connectionId']" } }, "method": "post", "path": "/Incidents/Comment", "body": { "incidentArmId": "@{body('Get_Incident')?['id']}", "message": "Automated triage and response completed:\n\n✅ Disabled @{length(body('Get_Entities')?['Accounts'])} compromised accounts\n✅ Revoked all active sessions\n✅ Isolated @{length(body('Get_Entities')?['Hosts'])} affected devices\n✅ Initiated full AV scans\n✅ Collected forensic investigation packages\n✅ Created ServiceNow ticket\n✅ Notified SOC team via Teams\n\nIncident ready for analyst review." } } } } } }

Performance & Cost Optimization: Efficient Hunting at Scale

Balans tussen zichtbaarheid, prestaties en kosten

Een krachtige SIEM‑ en huntingomgeving is alleen effectief wanneer zij zowel technisch als financieel duurzaam is. Microsoft Sentinel rekent primair af op de hoeveelheid data die wordt opgenomen en verwerkt. Voor een middelgrote of grote overheidsorganisatie kan het al snel gaan om vele terabytes per maand. Zonder bewuste keuzes op het gebied van datacollectie, bewaartermijnen en queryontwerp lopen kosten op en neemt de prestaties van hunting‑werkzaamheden af. Tegelijkertijd dwingt de Baseline Informatiebeveiliging Overheid (BIO) tot ruime logretentie, juist zodat incidenten achteraf grondig kunnen worden onderzocht. Het is dus noodzakelijk om een evenwicht te vinden waarin voldoende zichtbaarheid wordt behouden, maar verspilling wordt voorkomen.

Een belangrijk stuurmiddel is het gebruik van verschillende bewaarlagen. In de praktijk betekent dit dat recente gegevens, bijvoorbeeld de laatste drie maanden, beschikbaar blijven in de zogenoemde hot‑tier waar queries snel kunnen worden uitgevoerd. Deze periode is cruciaal voor dagelijks SOC‑werk en voor actieve threat hunting, omdat de meeste verdachte activiteiten binnen dit venster zullen worden onderzocht. Oudere gegevens kunnen, mits goed gepland, worden verplaatst naar een goedkopere archieflaag. Daar blijven ze behouden voor forensische onderzoeken, audits en wettelijke verplichtingen, maar hoeven ze niet continu met dezelfde snelheid doorzoekbaar te zijn. Door per logcategorie te bepalen welke bewaartermijn in welke laag nodig is, kan de organisatie kosten aanzienlijk reduceren zonder afbreuk te doen aan de naleving van de BIO.

Minstens zo belangrijk is de vraag welke logbronnen in de eerste plaats worden opgenomen. Niet elke applicatie‑log draagt evenveel bij aan het detecteren van geavanceerde aanvallen. In het algemeen leveren identiteits‑ en toegangslogs, endpointtelemetrie, e‑mail‑ en samenwerkingslogs en kernlogboeken van kritieke systemen de meeste waarde voor threat hunting. Ze geven inzicht in wie wat doet, met welke rechten en op welke systemen. Zeer gedetailleerde debuglogs of sterk technische applicatielogs kunnen veel volume genereren terwijl ze slechts marginaal bijdragen aan het herkennen van een aanvalspatroon. Door gebruik te maken van Data Collection Rules (DCR’s) kan al bij de bron worden gefilterd welke categorieën worden doorgestuurd naar Sentinel en welke in een goedkoper, minder vaak geraadpleegd archief terechtkomen.

Naast beheersing van ingestiekosten speelt query‑ontwerp een grote rol in de totale verwerkingskosten. Iedere query die over een lange periode of brede dataset wordt uitgevoerd, verbruikt rekenkracht. Door voor elke hunting‑query vooraf te schatten hoeveel data er ongeveer wordt verwerkt, bijvoorbeeld met behulp van functies die de datasize ramen, kan een analist bewustere keuzes maken. Soms blijkt een hypothese ook te testen op een kleinere subset, zoals alleen domeincontrollers of alleen hooggevoelige datasets, waardoor de kosten dalen zonder dat de relevantie van de resultaten afneemt. Het expliciet opnemen van tijdsfilters, het beperken van kolommen en het vermijden van onnodige joins helpt bovendien om onverwacht hoge belasting te voorkomen.

Voor grote omgevingen is ook de inrichting van de werkruimtes van belang. Het kan zinvol zijn om aparte Sentinel‑workspaces te hanteren voor productie‑ en testomgevingen of voor logtypen met sterk uiteenlopend volume en waarde, zoals firewall‑ en proxylogs. Daarmee worden zware query’s op minder kritieke data gescheiden van analyses op kernsystemen, zodat deze elkaar niet hinderen. Cross‑workspacequeries blijven mogelijk, maar worden alleen ingezet wanneer dat echt nodig is, bijvoorbeeld om een incident te reconstrueren dat over meerdere omgevingen heen gaat. Zo blijft de dagelijkse hunting‑praktijk wendbaar en voorspelbaar.

Bij al deze optimalisaties mag de naleving van de BIO‑retentie‑eisen niet uit het oog worden verloren. Die schrijven onder meer voor dat beveiligingsgebeurtenissen minimaal een jaar beschikbaar moeten blijven en dat logs rond beheerhandelingen en incidenten vaak langer bewaard moeten worden. Sentinel kan hierin ondersteunen door standaardbewaartermijnen per tabel in te stellen, ouder materiaal automatisch naar goedkopere opslaglagen te verplaatsen en waar nodig export naar onveranderbare opslag (WORM) te faciliteren. Door logcategorieën te koppelen aan concrete BIO‑artikelen en bewaartermijnen, kan een CISO richting auditors uitleggen hoe de technische configuratie aansluit bij de vereisten.

Efficiënte hunting op grote schaal is daarmee geen kwestie van één instelling, maar van een samenhangend geheel aan keuzes rond datacollectie, architectuur en query‑ontwerp. Door in ontwerp‑ en beheerprocessen expliciet aandacht te besteden aan prestaties en kosten, ontstaat een omgeving waarin analisten snel en flexibel kunnen zoeken zonder dat iedere nieuwe use‑case leidt tot onverwachte financiële verrassingen. Zo blijft Microsoft Sentinel een krachtig, maar beheersbaar instrument om de digitale weerbaarheid van de Nederlandse overheid blijvend te versterken.

Microsoft Sentinel threat hunting transformeert security operations van reactive incident response naar proactive threat detection. Voor Nederlandse overheidsdiensten onder BIO-richtlijnen is een mature hunting program niet langer optioneel – het is een hard requirement voor effective cyber defense tegen state-sponsored APTs en sophisticated ransomware campaigns.

De sleutel tot succesvolle threat hunting ligt in structured methodologies (hypothesis-driven en intelligence-led), geavanceerde KQL query skills, behavioral analytics via UEBA, en systematische automation van proven hunting queries. Een mature hunting program detecteert threats binnen minuten tot uren, vergeleken met dagen tot maanden bij traditional reactive detection.

Start vandaag met het opbouwen van uw hunting capabilities: enable Sentinel UEBA entities, import threat intelligence feeds, train uw SOC team in advanced KQL, en implementeer scheduled hunting queries voor continuous monitoring. De investering in proactive hunting betaalt zich direct terug in drastisch reduced dwell time, early attack chain disruption, en compliance met BIO Norm 12.4 en NIS2 incident detection requirements.

Bekijk onze Sentinel deployment scripts en hunting query library
Bekijk artikelen →
Microsoft Sentinel Threat Hunting SIEM KQL BIO Compliance SOC Incident Response