← All articlesSecurity

Advanced Threat Hunting with Security Copilot and KQL

Ishfaq Nazir · Microsoft & Azure Cloud Security Architect 10/10/2026 11 min read

From question to query

Threat hunting starts with a hypothesis: "An attacker used a stolen token to access mailboxes." Turning that into KQL takes skill. Security Copilot's natural language to KQL capability in Defender XDR advanced hunting and Microsoft Sentinel closes that gap — while experienced hunters still refine the output.

1. Workflow

  1. Write the hypothesis in plain English.
  2. Ask Copilot to generate KQL in the advanced hunting pane.
  3. Review the query – check tables, time ranges and joins.
  4. Run, then ask Copilot to summarise results.
  5. Save successful hunts as custom detection rules or KQL plugins.

2. Hunt: impossible travel and token theft

Prompt: "Show users who signed in successfully from two different countries within one hour in the last 7 days."

SigninLogs
| where TimeGenerated > ago(7d) and ResultType == 0
| project TimeGenerated, UserPrincipalName, Country = tostring(LocationDetails.countryOrRegion), IPAddress
| sort by UserPrincipalName asc, TimeGenerated asc
| extend PrevCountry = prev(Country), PrevTime = prev(TimeGenerated), PrevUser = prev(UserPrincipalName)
| where UserPrincipalName == PrevUser and Country != PrevCountry
| where datetime_diff('minute', TimeGenerated, PrevTime) < 60

Follow up with Copilot: "For these users, list any new inbox rules created afterwards."

CloudAppEvents
| where Timestamp > ago(7d)
| where ActionType in ("New-InboxRule", "Set-InboxRule")
| extend Rule = tostring(RawEventData.Parameters)
| where Rule has_any ("DeleteMessage", "MoveToFolder", "RSS")
| project Timestamp, AccountDisplayName, IPAddress, Rule

3. Hunt: lateral movement on endpoints

Prompt: "Find remote service creation or PsExec usage across devices in the last 3 days."

DeviceProcessEvents
| where Timestamp > ago(3d)
| where FileName in~ ("psexec.exe", "psexesvc.exe")
   or (FileName =~ "sc.exe" and ProcessCommandLine has_all ("create", "\\"))
| summarize Count = count(), Targets = make_set(DeviceName) by InitiatingProcessAccountName
| order by Count desc

Ask Copilot to map the findings to MITRE ATT&CK T1021 (Remote Services) and T1569.002 (Service Execution).

4. Hunt: suspicious OAuth consent

AuditLogs
| where TimeGenerated > ago(14d)
| where OperationName == "Consent to application"
| extend App = tostring(TargetResources[0].displayName),
         User = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, User, App, Result

Prompt Copilot: "Summarise the permissions these apps requested and flag any with Mail.ReadWrite or Files.ReadWrite.All."

5. Script and file analysis

Paste an obfuscated PowerShell command into Security Copilot and ask "Explain what this script does and list IOCs." Copilot decodes Base64, identifies download cradles and C2 domains, and you can pivot those IOCs into a DeviceNetworkEvents hunt.

6. Operationalise

  • Custom detections in Defender XDR run hunting queries on a schedule and raise alerts.
  • Sentinel analytics rules with entity mapping for incidents.
  • Logic Apps + Security Copilot connector to auto-enrich incidents with summaries.
  • KQL plugins in Security Copilot to package your best hunts as reusable skills for junior analysts.

7. Best practices

  • Always constrain time ranges to control cost and performance.
  • Validate generated queries — AI can choose the wrong table or field.
  • Keep a hunting notebook (Sentinel Notebooks or a Git repository).
  • Track hunts that became detections as a programme metric.

Conclusion

Security Copilot lowers the barrier to KQL, and KQL gives Copilot precision. Together they let analysts move from hypothesis to evidence to detection faster than ever.

#Security Copilot#KQL#Threat Hunting#Sentinel#Defender XDR

Related articles