This KQL query grabs defined RMM domains within the Splunk Security Content 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 CSV.
let RMMs = externaldata(description:string,remote_domain:string,remote_utility:string,remote_utility_fileinfo:string,remote_appid:string,isutility:string,category:string,comment_reference:string,last_update:string) [ @'https://raw.githubusercontent.com/splunk/security_content/develop/lookups/remote_access_software20240726.csv'] with (format="csv",ignoreFirstRecord=true);
// ----------------------------------------------------------------
// Create a list of defined domains.
let RMMDomains = RMMs | distinct tostring(remote_domain) | where isnotempty( remote_domain ) | summarize make_set(remote_domain);
// ----------------------------------------------------------------
// 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)
| extend TLD = extract(@'\.([^\.]+\.[^\.]+)$',1,Host)
| 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 TLD