This KQL query grabs defined RMM domains within the RMML project and matches them against MDE telemetry.
See also the original blog post here.
// Define the regex constructor function which transforms an array of patterns into regex.
let regexConstructor = (arr:dynamic) { replace_string( replace_string(replace_string( replace_string(strcat('((?i)', strcat_array( arr,'|') ,')'), '.','[.]'), @'\',@'\\'), @'/',@'\/'), @'*', @'.*') };
// ----------------------------------------------------------------
// Download the JSON string and convert to a usable object.
let RMMs = externaldata(RMMs:string)[h@'https://github.com/LivingInSyn/RMML/releases/download/v1.4.0/rmms.json'] with(format='raw');
let ParsedRMMs = RMMs
| extend RMMs = todynamic(extract_json('$',RMMs))
| mv-apply Tool = bag_keys(RMMs) on ( extend T = RMMs["Tool"] )
| extend JSON = RMMs[tostring(Tool)]
| project-away RMMs,T;
// ----------------------------------------------------------------
// Create a list of defined domains.
let RMMDomains = ParsedRMMs | project Domains = JSON.NetConn.Domains | mv-expand Domains | distinct tostring(Domains) | where isnotempty( Domains ) | summarize make_set(Domains);
// ----------------------------------------------------------------
// Call the regex constructor function with the list of domains.
let RMMDomainsRegex = replace_regex(regexConstructor(toscalar(RMMDomains)),@'https?:\\/\\/','');
// ----------------------------------------------------------------
// Start matching these domains within your network telemetry.
DeviceNetworkEvents
| where RemoteUrl has_any (RMMDomains) or
RemoteUrl matches regex RMMDomainsRegex
| extend Host = extract('(http(s)?://)?([^/$:]+)',3,RemoteUrl)
| summarize URLs = make_set(RemoteUrl),
URLCount = dcount(RemoteUrl),
Hosts = make_set(DeviceName),
HostCount = dcount(DeviceName),
Users = make_set(InitiatingProcessAccountName),
UserCount = dcount(InitiatingProcessAccountName),
Files = make_set(tolower(InitiatingProcessFileName)) by Host