5 minutes
Detecting RMM
(originally posted on github)
The most difficult challenge with RMM detection is contextual awareness around usage to determine if it is valid or malicious.
- if the software is not used in the environment
- could it be legitimate by a random employee?
- is it an attacker BYOL
- even so, all occurrences could probably be considered suspicious
- if it is used in the environment
- is every use of it legitimate? Probably not
- this also creates significant living off the land (LOL) opportunity
- some occurrences should be considered suspicious
- without any contextual awareness, this is an even harder problem
Under resources, there is a table of known RMM executables, as well as a raw json RMM.json for processing.
Approaches to detecting
A. Explicitly defined RMM software + behavioral (less resilient)
These rely on explicity referencing known RMM artifacts (in some way) within the logic
- Known RMMs
- Known RMM + low prevalence
- New executable in environment + known RMM
- New + RMM + suspicious activity
- New + RMM + alert
B. Dynamically and generically defining RMM + behavioral
This relies completely on common behaviors of RMM (can misidentify)
- Logic for generic RMM behaviors (vs pre-defined known RMMs)
Details
A1. Known RMMs
Two options to defining known RMM’s
Option 1: comprehensive list of identified RMM executables
Simply build a list of all known executables (see the table below). This is brittle, but more precise
process where event.type == "start" and
(
// Windows
(
host.os.type == "windows" and
process.executable : (
"C:\\Program Files*\\*\\NinjaRMMAgentPatcher.exe",
"C:\\Program Files*\\NinjaRMMAgent\\NinjaRMMAgentPatcher.exe",
"C:\\ProgramData\\NinjaRMMAgent\\ninjarmm-cli.exe",
"C:\\Program Files*\\*\\NinjaRMMAgent.exe",
"C:\\Program Files*\\NinjaRMMAgent\\NinjaRMMAgent.exe",
"C:\\Program Files*\\ATERA Networks\\AteraAgent\\AteraAgent.exe",
"C:\\Program Files*\\ATERA Networks\\AteraAgent\\Packages\\AgentPackageNetworkDiscoveryWG\\AgentPackageNetworkDiscoveryWG.exe",
"C:\\Program Files*\\ATERA Networks\\AteraAgent\\Packages\\AgentPackageAgentInformation\\AgentPackageAgentInformation.exe",
"C:\\Program Files*\\ATERA Networks\\AteraAgent\\Packages\\AgentPackageSTRemote\\AgentPackageSTRemote.exe",
"C:\\Program Files*\\ATERA Networks\\AteraAgent\\Packages\\AgentPackageFileExplorer\\AgentPackageFileExplorer.exe",
"C:\\Program Files*\\ATERA Networks\\AteraAgent\\Packages\\AgentPackageMonitoring\\AgentPackageMonitoring.exe",
"C:\\Program Files*\\ATERA Networks\\AteraAgent\\Packages\\AgentPackageRuntimeInstaller\\AgentPackageRuntimeInstaller.exe",
"C:\\Windows\\SysWOW64\\config\\systemprofile\\AppData\\Local\\GoToAssist Remote Support Applet\\*.tmp\\GoToAssistService.exe",
"C:\\Users\\*\\AppData\\Local\\GoToAssist Remote Support Applet\\*.tmp\\GoToAssistProcessChecker.exe",
"C:\\Program Files*\\LogMeIn\\GoToAssist Corporate\\*\\G2AC_HostLauncher.exe",
"C:\\Program Files*\\GoToMeeting\\*\\G2MInstaller.exe",
"C:\\Users\\*\\AppData\\Local\\GoToMeeting\\*\\g2mcomm.exe",
"C:\\Users\\*\\AppData\\Local\\GoToMeeting\\*\\g2mlauncher.exe",
"C:\\Program Files*\\GoToAssist Remote Support Customer\\*\\g2ax_host_service.exe",
"C:\\Program Files*\\GoToAssist Remote Support Customer\\*\\g2ax_comm_customer.exe",
"C:\\Users\\*\\AppData\\Local\\GoTo Resolve Applet\\*.tmp\\GoToResolveService.exe",
"C:\\Program Files*\\GoToAssist Remote Support Unattended\\*\\GoToAssistTools64.exe",
"C:\\Program Files*\\GoToAssist Remote Support Unattended\\*\\GoToAssistUnattended.exe",
"C:\\Users\\*\\AppData\\Local\\goto-updater\\pending\\GoToSetup-*.exe",
"C:\\Program Files*\\GoToMeeting\\*\\g2mlauncher.exe",
"C:\\Users\\*\\AppData\\Local\\GoToAssist Remote Support Applet\\*.tmp\\GoToAssistCrashHandler.exe",
"C:\\Users\\*\\AppData\\Local\\GoToMeeting\\*\\g2mupdate.exe",
"C:\\ManageEngine\\DesktopCentralMSP_Server\\jre\\bin\\java.exe",
"C:\\ManageEngine\\ADManager Plus\\jre\\bin\\java.exe",
"C:\\Program Files*\\ManageEngine\\PMP\\tools\\archiver\\windows\\x86-64\\7za.exe",
"C:\\ManageEngine\\elasticsearch\\jre\\bin\\java.exe",
"C:\\Program Files*\\ManageEngine\\PMP\\jre\\bin\\java.exe",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\bin\\7za.exe",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\bin\\wrapper.exe",
"C:\\ManageEngine\\OpManager\\jre\\bin\\java.exe",
"C:\\ManageEngine\\EventLog Analyzer\\jre\\bin\\java.exe",
"C:\\ManageEngine\\ADAudit Plus\\pgsql\\bin\\postgres.exe",
"C:\\ManageEngine\\OpManager\\Probe\\OpManagerProbe\\pgsql\\bin\\postgres.exe",
"C:\\Program Files*\\Microsoft Intune Management Extension\\ClientHealthEval.exe",
"C:\\Program Files*\\WindowsApps\\Microsoft.*\\IntuneManagementExtensionBridge\\IntuneManagementExtensionBridge.exe",
"C:\\Program Files*\\WindowsApps\\Microsoft.*\\BridgeLauncher\\BridgeLauncher.exe",
"C:\\Program Files*\\Microsoft Intune Management Extension\\Microsoft.Management.Services.IntuneWindowsAgent.exe",
"C:\\Program Files*\\Microsoft Intune Management Extension\\Microsoft.Management.Clients.CopyAgentCatalog.exe",
"C:\\Program Files*\\Microsoft Intune Management Extension\\SensorLogonTask.exe",
"C:\\Program Files*\\Microsoft Intune Management Extension\\AgentExecutor.exe",
"C:\\Users\\*\\AppData\\Local\\MSP Anywhere for N-central\\Viewer\\Tmp\\SWI_MSP_RC_ViewerUpdate-*.exe",
"C:\\Program Files*\\DesktopCentral_Agent\\bin\\dcagentservice.exe",
"C:\\Program Files*\\DesktopCentral_Agent\\bin\\DCFAService64.exe",
"C:\\Program Files*\\DesktopCentral_Agent\\bin\\dcagentregister.exe",
"C:\\Program Files*\\DesktopCentral_Server\\pgsql\\bin\\postgres.exe",
"C:\\Program Files*\\DesktopCentral_Server\\bin\\wrapper.exe",
"C:\\ManageEngine\\DesktopCentral_Server\\bin\\wrapper.exe",
"C:\\Program Files*\\DesktopCentral_Server\\bin\\UEMS.exe",
"C:\\Program Files*\\DesktopCentral_Server\\nginx\\dcnginx.exe",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\jre\\bin\\java.exe",
"C:\\Program Files*\\DesktopCentral_Agent\\bin\\EMSAddonInstaller.exe",
"C:\\ManageEngine\\DesktopCentral_Server\\jre\\bin\\java.exe",
"C:\\Program Files*\\DesktopCentral_Server\\apache\\bin\\dcserverhttpd.exe",
"C:\\Program Files*\\DesktopCentral_Server\\bin\\7za.exe",
"C:\\Program Files*\\DesktopCentral_Server\\jre\\bin\\java.exe",
"C:\\Program Files*\\DesktopCentral_Server\\bin\\dcnotificationserver.exe",
"C:\\Program Files*\\DesktopCentral_Agent\\dcconfig.exe",
"C:\\Program Files*\\DesktopCentral_Agent\\patches\\*-gimp-*-setup.exe",
"C:\\ManageEngine\\AssetExplorer\\DesktopCentral_Server\\bin\\wrapper.exe",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\lib\\native\\64bit\\wrapper.dll",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\jre\\bin\\awt.dll",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\jre\\bin\\sunec.dll",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\jre\\bin\\freetype.dll",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\jre\\bin\\fontmanager.dll",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\lib\\native\\64bit\\SyMNative.dll",
"C:\\Program Files*\\ManageEngine\\ServiceDesk\\DesktopCentral_Server\\lib\\native\\64bit\\OSDSyMNative.dll",
"C:\\Windows\\Action1\\action1_remote.exe",
"C:\\Windows\\Action1\\action1_agent.exe")
) or
// MacOS
(
host.os.type == "macos" and
process.executable : (
"/Applications/NinjaRMMAgent/programfiles/ninjarmm-macagent",
"/Applications/GoToMeeting.app/Contents/MacOS/GoToMeeting",
"/Applications/GoToMeeting.app/Contents/Helpers/G2MUpdate",
"/Users/*/Library/Application Support/LogMeInInc/GoToMeeting/G2MUpdate",
"/Library/Intune/Microsoft Intune Agent.app/Contents/MacOS/IntuneMdmDaemon",
"/Applications/MSP Anywhere Agent N-central.app/Contents/Resources/MSP Anywhere Service Configurator.app/Contents/MacOS/MSP Anywhere Service Configurator",
"/Applications/MSP Anywhere Agent N-central.app/Contents/Resources/MSP Anywhere Helper")
)
)
Option 2: resilient patterns of known RMM software
This is a more resilient approach, which looks for
- unique patterns of the executable path
- code signature unique to RMM software
any where event.category : ("process", "library") and event.type == "start" and
(
// Windows
(
host.os.type == "windows" and (
process.executable : ("?:\\*NinjaRMMAgent*.exe",
"?:\\*\\AteraAgent\\*.exe",
"?:\\*\\GoToAssist*\\*.exe", "?:\\*\\GoToMeeting\\*.exe", "?:\\*\\GoTo*.exe", "?:\\*\\GoToSetup*.exe",
"?:\\*ManageEngine\\*.exe",
"?:\\Microsoft Intune*\\*.exe", "?:\\IntuneManagement*\\*.exe",
"?:\\*\\*N-central*\\*.exe",
"?:\\*\\DesktopCentral*\\*.exe",
"?:\\*\\Action1\\*.exe") or
dll.path : ("?:\\*NinjaRMMAgent*.dll",
"?:\\*\\AteraAgent\\*.dll",
"?:\\*\\GoToAssist*\\*.dll", "?:\\*\\GoToMeeting\\*.dll", "?:\\*\\GoTo*.dll", "?:\\*\\GoToSetup*.dll",
"?:\\*ManageEngine\\*.dll",
"?:\\Microsoft Intune*\\*.dll", "?:\\IntuneManagement*\\*.dll",
"?:\\*\\*N-central*\\*.dll",
"?:\\*\\DesktopCentral*\\*.dll",
"?:\\*\\Action1\\*.dll") or
process.code_signature.subject_name : ("NinjaRMM, LLC",
"Atera Networks Ltd",
"LogMeIn, Inc.",
"ZOHO Corporation Private Limited", // could FP due to non-RMM software
"Action1 Corporation") or
dll.code_signature.subject_name : ("NinjaRMM, LLC",
"Atera Networks Ltd",
"LogMeIn, Inc.",
"ZOHO Corporation Private Limited", // could FP due to non-RMM software
"Action1 Corporation")
)
) or
// MacOS
(
host.os.type == "macos" and (
process.executable : ("/Applications/*NinjaRMMAgent/*",
"/Applications/*GoToMeeting*/*", "/Users/*/Library/*/GoToMeeting*/*",
"/Library/*Microsoft InTune*/*", "/Users/*/Library/*Microsoft InTune*/*",
"/Applications/*N-central*/*") or
// or dll.path : () or
// process.code_signature.subject_name : () or
// dll.code_signature.subject_name : ()
)
)
// Linux
)
A2. Known RMM + low prevalence
Perform one of the searches from step 1 and aggregate on:
- hosts
- users
- unique executions
Look for low counts
A3. New executable in environment + known RMM
Create a new terms stlye rule based on step 1
- window history of now-30d
- base the new terms on:
process.name
,host.id
(remove host.id for full environment prevalence)
If you do not have a new terms capability, you can perform the search in step 1 to build a list of observed RMM executables,
then pivot (or join
) on a search for recent exections.
A4. New executable + known RMM + suspicious activity
Combine step 3 with subsequent suspicious activity (such as lateral movement information gathering).
With Elastic, you could do this by:
- create the rule from step 3 (optionally as a
building_block_rule
to keep noise down) - create a separate sequence based rule that looks for the new term then the suspicious activity
- to simplify this, you can create another
building_block_rule
for suspicious activity
- to simplify this, you can create another
sequence by host.id, user.id, process.name with maxspan=25m
[alert where rule.id == <new_term_rule_step3>]
[alert where rule.id == <suspicious_rule_step4>]
A5. New executable + known RMM + alert
Similar to step 4 except referencing actual alerts for the second part of the sequence
sequence by host.id, user.id, process.name with maxspan=25m
[alert where rule.id == <new_term_rule_step3>]
[alert where true]
Leaving subquery 2 generic is a great option, since a newly occurring RMM would be suspicious in this case. It can be tightened down with a few options:
- limiting query 2 to certain techniques or subtechniques
- add additional logic to query 2 from the raw alert results, or even a subset of alerts
- adding additional queries to the sequence to express a more progressed attack
B1. Logic for generic RMM behaviors
Rather than using statically defined RMM artifacts based on observations, this entails building out generic logic to identify them. This is a much greater challenge, especially due to their legitimate nature. Additional features such as ML, entity analytics, and other aggregation based searching make a significant difference here.
Once a dynamic method is defined, then steps 2-5 apply, creating a sustainable detection approach.
I think it is doable from a purely rule-based approach, but I will return to this a bit later …
Also, with the Elastic ES|QL piped language, these become much more feasible within a single rule.