M365 Advanced Hunting Query

Find Active Directory user accounts that have been inactive for more than 30 days.
// KQL

IdentityLogonEvents 
| project Timestamp, AccountName, 
DeviceName, LogonType
| summarize LastLogon = max(Timestamp) 
by AccountName, LogonType, DeviceName
| where LastLogon < ago(30d)
Identifies applications which leverage a command line pattern which matches the 7zip and WinRAR command line executables to create or update an archive when a password is specified
// KQL

DeviceProcessEvents
| where ProcessCommandLine matches regex @"\s[aukfAUKF]\s.*\s-p" // Basic 
filter to look for launch string
| extend SplitLaunchString = split(ProcessCommandLine, ' ') // Split on the 
space
| where array_length(SplitLaunchString) >= 5 and SplitLaunchString[1] in~ 
('a','u','k','f') // look for calls to archive or update an archive specifically 
as the first argument
| mv-expand SplitLaunchString // cross apply the array
| where SplitLaunchString startswith "-p" // -p is the password switch and is 
immediately followed by a password without a space
| extend ArchivePassword = substring(SplitLaunchString, 2, 
strlen(SplitLaunchString))
| project-reorder ProcessCommandLine, ArchivePassword // Promote these fields to 
the left

Identify strings in process command lines which match Base64 encoding format, extract the string to a column called Base64, and decode it in a column called Decoded String.
// KQL

DeviceProcessEvents
| extend SplitLaunchString = split(ProcessCommandLine, " ")
| mvexpand SplitLaunchString
| where SplitLaunchString matches regex "^[A-Za-z0-9+/]{50,}[=]{0,2}$"
| extend Base64 = tostring(SplitLaunchString)
| extend DecodedString = base64_decodestring(Base64)
| where isnotempty(DecodedString)
Identify which files within the last 24 hours had more then 10 data access, download or deletion activities on MCAS-protected applications.
// KQL

AppFileEvents
| where Timestamp > ago(1d)
| summarize count() by FolderPath, 
FileName, ActionType, 
AccountDisplayName
| where count_ > 10
Pull SHA256 out of text file and look for Email attachments that matches the SHA256
// KQL

let abuse_sha256 = 
(externaldata(sha256_hash: string )
[@"https://bazaar.abuse.ch/export/txt/sha2
56/recent/"]
with (format="txt"))
| where sha256_hash !startswith "#"
| project sha256_hash;
abuse_sha256
| join (EmailAttachmentInfo 
| where Timestamp > ago(1d) 
) on $left.sha256_hash == $right.SHA256
| project Timestamp,SenderFromAddress 
,RecipientEmailAddress,FileName,FileType,S
HA256, 
MalwareFilterVerdict,MalwareDetectionMethod
Finds PowerShell execution events that could involve a download
// KQL 

union DeviceProcessEvents, DeviceNetworkEvents
| where Timestamp > ago(7d)
| where FileName in~ ("powershell.exe", "powershell_ise.exe")
| where ProcessCommandLine has_any("WebClient",
"DownloadFile",
"DownloadData",
"DownloadString",
"WebRequest",
"Shellcode",
"http",
"https")
| project Timestamp, DeviceName, InitiatingProcessFileName, 
InitiatingProcessCommandLine, 
FileName, ProcessCommandLine, RemoteIP, RemoteUrl, RemotePort, RemoteIPType
| top 100 by Timestamp 
Identity + Endpoint: Lookup processes that performed LDAP auth. with clear text passwords
Lookup for emails coming into the organization from an external source that was targeted to more than 50 distinct corporate users
Lookup for all emails within last 7 days where the malware verdict was Malware

Last updated