Advanced Hunting is a powerful, query-based, threat-hunting tool included in the Microsoft 365 Defender platform. When utilized properly, advanced hunting can uncover initial access of a threat actor, lateral movement, exfiltration, insider threats, and so much more.
In this post, I will be going through Microsoft’s Community GitHub repo containing advanced hunting queries and showing you my five favorite queries. The full repo can be found here.
Note:
If you want to set up a free lab environment with Microsoft Defender for Endpoint, check out this blog post to get you started:
Create a Free Lab with Microsoft Defender for Endpoint and Simulate a Ransomware Attack
Advanced Hunting Queries
Just a quick note before we dive into these queries:
No single cybersecurity tool should be considered a catch-all solution to the challenges we face when protecting our infrastructures. Threat actors are creative and evasive and often times defensive security professionals feel like they are a step behind as they try to protect themselves against new and emerging threats.
What is so fantastic about advanced hunting queries is the only limitation to what you can discover is your own creativity. So let’s get the creative juices pumping and jump into these queries!
#5. Insider Threat Detection
Insider threats are individuals, typically employees, who have authorized access to your organization’s assets and use that access to negatively impact your organization either unintentionally or with malicious intent. Insider threats may disclose private information to your competitors or to the general public.
Advanced hunting is the perfect tool to begin identifying and investigating suspicious behavior of potential insider threats.
This query is going to look for any emails sent from one of your employees to one of your competitors:
let competitorDomains = pack_array(“competitor1”, “competitor2”);
EmailEvents
| where RecipientEmailAddress has_any (competitorDomains)
| project TimeEmail = Timestamp, Subject, SenderFromAddress, RecipientEmailAddress, AccountName = tostring(split(SenderFromAddress, “@”)[0]);

Just replace competitor1 and competitor2 with your competitors domain names (or any domains that may be suspicious for your employees to be emailing for that matter!)
This query is one of several insider threat detection queries that were contributed by SEI National Insider Threat Center and the rest of those queries can be found: HERE I highly recommend checking out the other ones included there.
#4. Identify Potential Missed Phishing Campaigns
This query is a nice way to identify phishing campaigns launched against your organization that may have otherwise slipped under the radar:
EmailEvents | where SenderFromDomain != “corporatedomain.com” | summarize dcount(RecipientEmailAddress) by SenderFromAddress, NetworkMessageId, AttachmentCount, Sendtime = Timestamp | where dcount_RecipientEmailAddress > 50

This query will identify emails sent from outside your organization to more than 50 distinct users in your company.
Just replace corporatedomain.com with your company domain and feel free to change 50 to adjust the distinct user count. For the purpose of this demo I changed 50 to 0, but depending on the size of your organization, you may want to play around with this number.
This query was contributed to the Microsoft Community GitHub repo by Milad Aslaner so thanks to him.
#3. Failed Logon Attempts
Simple, yet effective. This query will find failed logon attempts on high value assets such as domain controllers. Just replace DeviceName1 and DeviceName2 with your actual device names, and feel free to add more devices to the query as needed. By default this will return results where more than 3 logon failures were found on a specific device, but you can adjust this number.
This query comes from Milad Aslaner and Makislev – so thank you to them!
DeviceLogonEvents
| where DeviceName in (“DeviceName1″,”DeviceName2”)
| where ActionType == “LogonFailed”
| summarize LogonFailures=count() by DeviceName, LogonType, InitiatingProcessCommandLine
| where LogonFailures > 3
| project LogonFailures, DeviceName, LogonType, InitiatingProcessCommandLine
| sort by LogonFailures desc

#2. Endpoint Antivirus Version Report
This powerful query will generate a report displaying your devices’ antivirus signature versions, engine versions, platform versions, last signature update time, and whether or not the antivirus is active or passive (AV mode).
This query is not only great for ensuring your antivirus is up to date, but also for detecting third-party antivirus compatibility issues if the AV mode result is anomalous. For example, if you are only using Windows Defender as your antivirus, yet this is showing the AV mode is passive, that can indicate another antivirus is present and causing Defender to go into passive mode.
This powerful query was contributed by Yuji Aoki and Julihooper, so thank you to them.
let avmodetable = DeviceTvmSecureConfigurationAssessment
| where ConfigurationId == “scid-2010” and isnotnull(Context)
| extend avdata=parsejson(Context)
| extend AVMode = iif(tostring(avdata[0][0]) == ‘0’, ‘Active’ , iif(tostring(avdata[0][0]) == ‘1’, ‘Passive’ ,iif(tostring(avdata[0][0]) == ‘4’, ‘EDR Blocked’ ,’Unknown’)))
| project DeviceId, AVMode;
DeviceTvmSecureConfigurationAssessment
| where ConfigurationId == “scid-2011” and isnotnull(Context)
| extend avdata=parsejson(Context)
| extend AVSigVersion = tostring(avdata[0][0])
| extend AVEngineVersion = tostring(avdata[0][1])
| extend AVSigLastUpdateTime = tostring(avdata[0][2])
| extend AVProductVersion = tostring(avdata[0][3])
| project DeviceId, DeviceName, OSPlatform, AVSigVersion, AVEngineVersion, AVSigLastUpdateTime, AVProductVersion, IsCompliant, IsApplicable
| join avmodetable on DeviceId
| project-away DeviceId1

#1. Antivirus Detections and Their Source
I really like this query, because this will allow defenders to query for antivirus detections in their environment and the results will include: the threat name, the file and folder path it originated from, the MD5 hash, the URL it originated from if applicable, as well as the process that initiated it. Kudos to the contributors of this one, Tali-Ash and Sco-Sim.
//Get the list of AV detections
let avDetections =
DeviceEvents
| where ActionType == “AntivirusDetection” and isnotempty(MD5)
| extend ParsedFields=parse_json(AdditionalFields)
| project Timestamp, DeviceName, ThreatName=tostring(ParsedFields.ThreatName), FileName, FolderPath, MD5;
//Get a list of file creations
let fileCreations =
DeviceFileEvents
| where (isnotempty(FileOriginReferrerUrl) or isnotempty(FileOriginUrl)) and isnotempty(MD5)
| project MD5, FileOriginUrl, FileOriginReferrerUrl, InitiatingProcessFileName, InitiatingProcessParentFileName;
//Join the file creations and AV detections on the MD5 of the file
avDetections | join kind=inner (fileCreations) on MD5
| project-away MD51 //Remove the duplicated MD5 field
| sort by Timestamp desc

Conclusion
Thank you for reading, I really enjoyed making this post, because I learned so much about advanced hunting queries and the creative ways they can be used.
These queries were all found in the Microsoft Advanced Hunting Queries GitHub, so if you want more, please do check it out with the link below.
If you enjoyed this post, consider subscribing below so you’ll be the first to see my new posts – it is free to subscribe 😉💗
Note:
If you like these five queries and want more, check out the Microsoft GitHub here: https://github.com/microsoft/Microsoft-365-Defender-Hunting-Queries
One thought on “5 Powerful Advanced Hunting Queries”