Unmanaged Remote-Access and RMM Tooling on Employee Endpoints
WindowsmacOS
TTP Hunt medium DPRK IT Worker FraudFamous ChollimaLaptop Farm
A fleet-wide sweep for the consumer remote-access and RMM software DPRK IT workers install to hand control of an employer-issued laptop to an operator overseas, with a per-device product count that flags the hosts running four or more of them.
What this hunt looks for
Where an operation has not gone as far as hardware, it reaches the laptop through ordinary remote-access software. Mandiant records GoToRemote/LogMeIn, GoToMeeting, Chrome Remote Desktop, AnyDesk, TeamViewer and RustDesk on victim laptops; Unit 42 adds Splashtop; ReliaQuest ranks AnyDesk, RustDesk, VS Code tunnelling and Chrome Remote Desktop; Microsoft adds JumpConnect and AnyViewer.
The signal is not that these tools exist, since many are legitimate IT software, but that one appears where it was never sanctioned, usually within days of issue. One tool is ambiguous; DTEX rates four or more on one endpoint as warranting investigation, and Mandiant advises monitoring for multiple remote-administration tools.
Zscaler adds an AnyDesk tampering signal: operators edit pwd_hash, pwd_salt and token_salt in its configuration to set an unattended-access password without the interactive dialog. The queries cover Windows and macOS in one list; the Cortex XQL query adapts Unit 42's published sweep.
- Technique
- Remote Access Tools abuse (MITRE ATT&CK T1219, T1219.002) on a corporate endpoint held by a fraudulently hired employee (T1078).
- Data sources
- EDR process telemetry, Software inventory, Code-signing certificate metadata, macOS application bundles and launchd configuration
- Last updated
- 2026-10-04
Indicators
The atomic values this hunt matches on, listed separately from the queries so they can be lifted into tooling that speaks none of the query languages below. Every value here is reported by one of the sources cited at the foot of this page.
| Type | Value | Note |
|---|---|---|
| Software | AnyDesk, RustDesk, TeamViewer, AnyViewer, Chrome Remote Desktop, Splashtop, GoToRemote/LogMeIn, GoToMeeting, JumpConnect, ScreenConnect, VS Code dev tunnels |
Named across Mandiant, Unit 42, ReliaQuest and Microsoft reporting on DPRK IT-worker operations; ScreenConnect is one of the products in the Unit 42 sweep. |
| Chrome extension ID | inomeogfingihgjfjlpeplalcfajhgai |
Chrome Remote Desktop extension, as matched in Unit 42's published sweep. |
| Chrome extension ID | gbchcmhmhahfdphkhkmpfmihenigjmpp |
Chrome Remote Desktop extension, as matched in Unit 42's published sweep. |
| Signer | Zhou Huabing |
Code-signing vendor Unit 42's query maps to RustDesk. |
| Signer | FleetDeck Inc, SimpleHelp Ltd, NetSupport Ltd, Atera Networks, ConnectWise LLC/Inc, Splashtop Inc |
Signing vendors Unit 42's query uses in place of process names. |
| Configuration key | pwd_hash, pwd_salt, token_salt |
AnyDesk configuration values operators set directly to enable unattended access without the interactive password dialog (Zscaler). |
Logic
Every query below implements these steps, so the same hunt returns the same result in each product.
- Collect: process starts and file writes on Windows and macOS endpoints
- Match: image is a remote-access client (AnyDesk, TeamViewer, RustDesk, Splashtop, ScreenConnect, GoTo, AnyViewer, Jump Desktop, others)
- Match: or a Chrome Remote Desktop extension id in a profile path, or AnyDesk config (service.conf, user.conf) written by another process
- Exclude: devices of IT-support and managed-service staff (replace the placeholder list)
- Report: devices with their distinct products, most first; escalate 4 or more (DTEX)
Queries
Defender / Sentinel KQL
Written for this site, from indicators reported by Unit 42, Mandiant, ReliaQuest, Microsoft, DTEX, ZscalerRows are devices running any listed product, most products first; Escalate marks the DTEX threshold of four, and the ExcludedDevices list is a placeholder to fill.
// Hunt: unmanaged remote-access and RMM tooling. Names are matched without .exe, so the Windows and macOS binaries share one list.
let ExcludedDevices = dynamic([]); // replace with the device names of IT-support and managed-service staff
let Tools = datatable(Name:string, Product:string) [
"anydesk", "AnyDesk",
"teamviewer", "TeamViewer",
"teamviewer_service", "TeamViewer",
"tv_w32", "TeamViewer",
"tv_x64", "TeamViewer",
"rustdesk", "RustDesk",
"remoting_host", "Chrome Remote Desktop",
"srservice", "Splashtop",
"srmanager", "Splashtop",
"splashtopstreamer", "Splashtop",
"splashtop streamer", "Splashtop",
"meshagent", "MeshCentral",
"ateraagent", "Atera",
"client32", "NetSupport",
"pcilic", "NetSupport",
"pcideply", "NetSupport",
"screenconnect.clientservice", "ScreenConnect",
"connectwisecontrol.client", "ScreenConnect",
"screenconnect client", "ScreenConnect",
"g2comm", "GoToMeeting",
"gotoassist", "GoToRemote/LogMeIn",
"lmiguardiansvc", "GoToRemote/LogMeIn",
"lmi_rescue", "GoToRemote/LogMeIn",
"aeroadmin", "AeroAdmin",
"dwrcs", "DameWare",
"supremo", "Supremo",
"winvnc", "UltraVNC",
"tvnserver", "TightVNC",
// optional: Quick Assist ships with Windows and is routine in support sessions
"quickassist", "Quick Assist",
"fleetdeck_agent", "FleetDeck",
"simplehelpcustomer", "SimpleHelp",
"zohoassist", "Zoho Assist",
"action1_agent", "Action1",
"nomachine", "NoMachine",
"anyviewer", "AnyViewer",
"jumpconnect", "JumpConnect",
"jump desktop connect", "JumpConnect"
];
union
( DeviceProcessEvents
| where Timestamp > ago(90d)
| extend Name = replace_string(tolower(FileName), ".exe", "")
| lookup Tools on Name
| where isnotempty(Product)
| project Timestamp, DeviceName, Product, Signal = "process", Evidence = FolderPath ),
( DeviceFileEvents
| where Timestamp > ago(90d) and FolderPath has_any ("inomeogfingihgjfjlpeplalcfajhgai", "gbchcmhmhahfdphkhkmpfmihenigjmpp")
| project Timestamp, DeviceName, Product = "Chrome Remote Desktop", Signal = "extension-file", Evidence = FolderPath ),
( DeviceFileEvents
| where Timestamp > ago(90d) and ActionType in ("FileCreated", "FileModified") and FileName in~ ("service.conf", "user.conf")
| where FolderPath has "anydesk" and not(InitiatingProcessFileName in~ ("AnyDesk.exe", "AnyDesk"))
| project Timestamp, DeviceName, Product = "AnyDesk", Signal = "anydesk-config-edit", Evidence = strcat(InitiatingProcessFileName, " wrote ", FolderPath) )
| where DeviceName !in~ (ExcludedDevices)
| summarize ProductCount = dcount(Product), Products = make_set(Product),
Signals = make_set(Signal), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by DeviceName
| extend Escalate = ProductCount >= 4
| sort by ProductCount desc, FirstSeen desc
Lower-fidelity parts (1)
- the Quick Assist row of the Tools table — Quick Assist ships with Windows and is routine in support sessions. Remove: delete the // optional: Quick Assist comment and the row under it
Sigma
Written for this site, from indicators reported by Mandiant, Unit 42, ReliaQuestSingle-event rule for the product executables on Windows and macOS; the per-device product count is the Report step in the other queries.
title: Remote-Access Tool Executed on a Corporate Endpoint
id: b7f1ac4b-ec73-539d-b31e-619f2ec3e0d4
status: experimental
description: >
Detects execution of the consumer remote-access and RMM software repeatedly
named in DPRK IT-worker reporting, on Windows and macOS. On its own the
signal is weak, since much of this software is legitimate; it becomes strong
on a device where the tool is unsanctioned, within days of the device being
issued, or where four or more products run on one device.
references:
- https://cloud.google.com/blog/topics/threat-intelligence/mitigating-dprk-it-worker-threat
- https://unit42.paloaltonetworks.com/north-korean-it-workers/
- https://reliaquest.com/blog/threat-spotlight-identifying-north-korean-insider-threats
logsource:
category: process_creation
detection:
selection:
Image|endswith:
- '\anydesk.exe'
- '\teamviewer.exe'
- '\teamviewer_service.exe'
- '\tv_w32.exe'
- '\tv_x64.exe'
- '\rustdesk.exe'
- '\remoting_host.exe'
- '\srservice.exe'
- '\srmanager.exe'
- '\splashtopstreamer.exe'
- '\meshagent.exe'
- '\ateraagent.exe'
- '\client32.exe'
- '\pcilic.exe'
- '\pcideply.exe'
- '\screenconnect.clientservice.exe'
- '\connectwisecontrol.client.exe'
- '\g2comm.exe'
- '\gotoassist.exe'
- '\lmiguardiansvc.exe'
- '\lmi_rescue.exe'
- '\aeroadmin.exe'
- '\dwrcs.exe'
- '\supremo.exe'
- '\winvnc.exe'
- '\tvnserver.exe'
# optional: Quick Assist ships with Windows and is routine in support sessions
- '\quickassist.exe'
- '\fleetdeck_agent.exe'
- '\simplehelpcustomer.exe'
- '\zohoassist.exe'
- '\action1_agent.exe'
- '\nomachine.exe'
- '\anyviewer.exe'
- '\jumpconnect.exe'
- '/AnyDesk'
- '/TeamViewer'
- '/RustDesk'
- '/Splashtop Streamer'
- '/ScreenConnect Client'
- '/AnyViewer'
- '/Jump Desktop Connect'
condition: selection
falsepositives:
- Sanctioned IT support and managed-service tooling
level: medium
Lower-fidelity parts (1)
- the Quick Assist image — Quick Assist ships with Windows and is routine in support sessions. Remove: delete the # optional comment and the line under it
Splunk SPL
Written for this site, from indicators reported by Unit 42, DTEXCounts distinct products per host from process events; the NOT host line is a placeholder for the IT-support exclusion.
```Placeholder: index=endpoint is your EDR process events (Windows and macOS) with process_name and host extracted.```
index=endpoint process_name=*
| eval n=replace(lower(process_name), "[.]exe$", "")
| eval product=case(
match(n, "^(anydesk)$"), "AnyDesk",
match(n, "^(teamviewer|teamviewer_service|tv_w32|tv_x64)$"), "TeamViewer",
match(n, "^(rustdesk)$"), "RustDesk",
match(n, "^(remoting_host)$"), "Chrome Remote Desktop",
match(n, "^(srservice|srmanager|splashtopstreamer|splashtop streamer)$"), "Splashtop",
match(n, "^(meshagent)$"), "MeshCentral",
match(n, "^(ateraagent)$"), "Atera",
match(n, "^(client32|pcilic|pcideply)$"), "NetSupport",
match(n, "^(screenconnect[.]clientservice|connectwisecontrol[.]client|screenconnect client)$"), "ScreenConnect",
match(n, "^(g2comm)$"), "GoToMeeting",
match(n, "^(gotoassist|lmiguardiansvc|lmi_rescue)$"), "GoToRemote/LogMeIn",
match(n, "^(aeroadmin)$"), "AeroAdmin",
match(n, "^(dwrcs)$"), "DameWare",
match(n, "^(supremo)$"), "Supremo",
match(n, "^(winvnc)$"), "UltraVNC",
match(n, "^(tvnserver)$"), "TightVNC",
```optional: Quick Assist ships with Windows and is routine in support sessions```
match(n, "^(quickassist)$"), "Quick Assist",
match(n, "^(fleetdeck_agent)$"), "FleetDeck",
match(n, "^(simplehelpcustomer)$"), "SimpleHelp",
match(n, "^(zohoassist)$"), "Zoho Assist",
match(n, "^(action1_agent)$"), "Action1",
match(n, "^(nomachine)$"), "NoMachine",
match(n, "^(anyviewer)$"), "AnyViewer",
match(n, "^(jumpconnect|jump desktop connect)$"), "JumpConnect",
true(), null())
| where isnotnull(product)
| search NOT host IN ("replace-with-support-device")
| stats dc(product) AS product_count values(product) AS products min(_time) AS first_seen max(_time) AS last_seen BY host
| eval escalate=if(product_count >= 4, "yes", "no")
| sort - product_count - first_seen
| convert ctime(first_seen) ctime(last_seen)
Lower-fidelity parts (1)
- the Quick Assist case line — Quick Assist ships with Windows and is routine in support sessions. Remove: delete the ```optional comment and the match line under it
CrowdStrike LogScale
Written for this site, from indicators reported by Unit 42, DTEXCounts distinct products per device from ProcessRollup2; the in() exclusion holds a placeholder name.
// Hunt: unmanaged remote-access and RMM tooling. ImageFileName is a full path on both platforms.
#event_simpleName=ProcessRollup2
| !in(ComputerName, values=["replace-with-support-device"])
| case {
ImageFileName=/(^|[\\\/])(anydesk)(\.exe)?$/i | product := "AnyDesk";
ImageFileName=/(^|[\\\/])(teamviewer|teamviewer_service|tv_w32|tv_x64)(\.exe)?$/i | product := "TeamViewer";
ImageFileName=/(^|[\\\/])(rustdesk)(\.exe)?$/i | product := "RustDesk";
ImageFileName=/(^|[\\\/])(remoting_host)(\.exe)?$/i | product := "Chrome Remote Desktop";
ImageFileName=/(^|[\\\/])(srservice|srmanager|splashtopstreamer|splashtop streamer)(\.exe)?$/i | product := "Splashtop";
ImageFileName=/(^|[\\\/])(meshagent)(\.exe)?$/i | product := "MeshCentral";
ImageFileName=/(^|[\\\/])(ateraagent)(\.exe)?$/i | product := "Atera";
ImageFileName=/(^|[\\\/])(client32|pcilic|pcideply)(\.exe)?$/i | product := "NetSupport";
ImageFileName=/(^|[\\\/])(screenconnect\.clientservice|connectwisecontrol\.client|screenconnect client)(\.exe)?$/i | product := "ScreenConnect";
ImageFileName=/(^|[\\\/])(g2comm)(\.exe)?$/i | product := "GoToMeeting";
ImageFileName=/(^|[\\\/])(gotoassist|lmiguardiansvc|lmi_rescue)(\.exe)?$/i | product := "GoToRemote/LogMeIn";
ImageFileName=/(^|[\\\/])(aeroadmin)(\.exe)?$/i | product := "AeroAdmin";
ImageFileName=/(^|[\\\/])(dwrcs)(\.exe)?$/i | product := "DameWare";
ImageFileName=/(^|[\\\/])(supremo)(\.exe)?$/i | product := "Supremo";
ImageFileName=/(^|[\\\/])(winvnc)(\.exe)?$/i | product := "UltraVNC";
ImageFileName=/(^|[\\\/])(tvnserver)(\.exe)?$/i | product := "TightVNC";
// optional: Quick Assist ships with Windows and is routine in support sessions
ImageFileName=/(^|[\\\/])(quickassist)(\.exe)?$/i | product := "Quick Assist";
ImageFileName=/(^|[\\\/])(fleetdeck_agent)(\.exe)?$/i | product := "FleetDeck";
ImageFileName=/(^|[\\\/])(simplehelpcustomer)(\.exe)?$/i | product := "SimpleHelp";
ImageFileName=/(^|[\\\/])(zohoassist)(\.exe)?$/i | product := "Zoho Assist";
ImageFileName=/(^|[\\\/])(action1_agent)(\.exe)?$/i | product := "Action1";
ImageFileName=/(^|[\\\/])(nomachine)(\.exe)?$/i | product := "NoMachine";
ImageFileName=/(^|[\\\/])(anyviewer)(\.exe)?$/i | product := "AnyViewer";
ImageFileName=/(^|[\\\/])(jumpconnect|jump desktop connect)(\.exe)?$/i | product := "JumpConnect";
* | product := "";
}
| product != ""
| groupBy([aid, ComputerName], function=[count(product, distinct=true, as=productCount), collect([product]), min(@timestamp, as=firstSeen), max(@timestamp, as=lastSeen)])
| escalate := if(productCount >= 4, then="yes", else="no")
| sort(productCount, order=desc)
Lower-fidelity parts (1)
- the Quick Assist branch — Quick Assist ships with Windows and is routine in support sessions. Remove: delete the // optional comment and the line under it
Elastic
Written for this site, from indicators reported by Unit 42, ZscalerReads Elastic Defend process and file events; the Chrome extension and AnyDesk config-edit matches ride along in the same query.
FROM logs-endpoint.events.process-*, logs-endpoint.events.file-*
| WHERE @timestamp > NOW() - 90 days
| WHERE NOT host.name IN ("replace-with-support-device")
| EVAL tool = REPLACE(TO_LOWER(COALESCE(process.name, "")), "[.]exe$", "")
| EVAL path = TO_LOWER(COALESCE(file.path, ""))
| EVAL cfg = path RLIKE ".*anydesk.*" AND TO_LOWER(COALESCE(file.name, "")) IN ("service.conf", "user.conf") AND NOT tool IN ("anydesk")
| EVAL product = CASE(
cfg, "AnyDesk",
tool IN ("anydesk"), "AnyDesk",
tool IN ("teamviewer", "teamviewer_service", "tv_w32", "tv_x64"), "TeamViewer",
tool IN ("rustdesk"), "RustDesk",
tool IN ("remoting_host"), "Chrome Remote Desktop",
tool IN ("srservice", "srmanager", "splashtopstreamer", "splashtop streamer"), "Splashtop",
tool IN ("meshagent"), "MeshCentral",
tool IN ("ateraagent"), "Atera",
tool IN ("client32", "pcilic", "pcideply"), "NetSupport",
tool IN ("screenconnect.clientservice", "connectwisecontrol.client", "screenconnect client"), "ScreenConnect",
tool IN ("g2comm"), "GoToMeeting",
tool IN ("gotoassist", "lmiguardiansvc", "lmi_rescue"), "GoToRemote/LogMeIn",
tool IN ("aeroadmin"), "AeroAdmin",
tool IN ("dwrcs"), "DameWare",
tool IN ("supremo"), "Supremo",
tool IN ("winvnc"), "UltraVNC",
tool IN ("tvnserver"), "TightVNC",
tool IN ("quickassist"), "Quick Assist",
tool IN ("fleetdeck_agent"), "FleetDeck",
tool IN ("simplehelpcustomer"), "SimpleHelp",
tool IN ("zohoassist"), "Zoho Assist",
tool IN ("action1_agent"), "Action1",
tool IN ("nomachine"), "NoMachine",
tool IN ("anyviewer"), "AnyViewer",
tool IN ("jumpconnect", "jump desktop connect"), "JumpConnect",
path RLIKE ".*(inomeogfingihgjfjlpeplalcfajhgai|gbchcmhmhahfdphkhkmpfmihenigjmpp).*", "Chrome Remote Desktop",
NULL)
| WHERE product IS NOT NULL
| EVAL signal = CASE(cfg, "anydesk-config-edit", "product-seen")
| STATS product_count = COUNT_DISTINCT(product), products = VALUES(product), signals = VALUES(signal), first_seen = MIN(@timestamp), last_seen = MAX(@timestamp) BY host.name
| EVAL escalate = product_count >= 4
| SORT product_count DESC, first_seen DESC
Lower-fidelity parts (1)
- the Quick Assist CASE line — Quick Assist ships with Windows and is routine in support sessions. Remove: delete the CASE line that contains "quickassist"
Cortex XQL
Written for this site, from indicators reported by Unit 42 (Palo Alto Networks)Adapted from the Unit 42 RMM sweep: it adds the per-device product count, macOS names and the AnyDesk config-edit match, and keeps the signing-vendor checks that catch renamed binaries.
// Hunt: unmanaged remote-access and RMM tooling. Signing vendors catch renamed binaries (as in the Unit 42 sweep).
config case_sensitive = false timeframe = 90D
| dataset = xdr_data
| filter (event_type = ENUM.PROCESS and event_sub_type = ENUM.PROCESS_START) or event_type = ENUM.FILE
| filter agent_hostname not in ("replace-with-support-device")
| alter signal = if(event_type = ENUM.FILE and action_file_path ~= "(?i)anydesk" and action_file_name in ("service.conf", "user.conf") and actor_process_image_name not in ("AnyDesk.exe", "AnyDesk"), "anydesk-config-edit", "")
| alter product = if(
signal = "anydesk-config-edit", "AnyDesk",
action_process_image_name ~= "(?i)^(anydesk)([.]exe)?$", "AnyDesk",
action_process_image_name ~= "(?i)^(teamviewer|teamviewer_service|tv_w32|tv_x64)([.]exe)?$", "TeamViewer",
action_process_image_name ~= "(?i)^(rustdesk)([.]exe)?$", "RustDesk",
action_process_image_name ~= "(?i)^(remoting_host)([.]exe)?$", "Chrome Remote Desktop",
action_process_image_name ~= "(?i)^(srservice|srmanager|splashtopstreamer|splashtop streamer)([.]exe)?$", "Splashtop",
action_process_image_name ~= "(?i)^(meshagent)([.]exe)?$", "MeshCentral",
action_process_image_name ~= "(?i)^(ateraagent)([.]exe)?$", "Atera",
action_process_image_name ~= "(?i)^(client32|pcilic|pcideply)([.]exe)?$", "NetSupport",
action_process_image_name ~= "(?i)^(screenconnect[.]clientservice|connectwisecontrol[.]client|screenconnect client)([.]exe)?$", "ScreenConnect",
action_process_image_name ~= "(?i)^(g2comm)([.]exe)?$", "GoToMeeting",
action_process_image_name ~= "(?i)^(gotoassist|lmiguardiansvc|lmi_rescue)([.]exe)?$", "GoToRemote/LogMeIn",
action_process_image_name ~= "(?i)^(aeroadmin)([.]exe)?$", "AeroAdmin",
action_process_image_name ~= "(?i)^(dwrcs)([.]exe)?$", "DameWare",
action_process_image_name ~= "(?i)^(supremo)([.]exe)?$", "Supremo",
action_process_image_name ~= "(?i)^(winvnc)([.]exe)?$", "UltraVNC",
action_process_image_name ~= "(?i)^(tvnserver)([.]exe)?$", "TightVNC",
// optional: Quick Assist ships with Windows and is routine in support sessions
action_process_image_name ~= "(?i)^(quickassist)([.]exe)?$", "Quick Assist",
action_process_image_name ~= "(?i)^(fleetdeck_agent)([.]exe)?$", "FleetDeck",
action_process_image_name ~= "(?i)^(simplehelpcustomer)([.]exe)?$", "SimpleHelp",
action_process_image_name ~= "(?i)^(zohoassist)([.]exe)?$", "Zoho Assist",
action_process_image_name ~= "(?i)^(action1_agent)([.]exe)?$", "Action1",
action_process_image_name ~= "(?i)^(nomachine)([.]exe)?$", "NoMachine",
action_process_image_name ~= "(?i)^(anyviewer)([.]exe)?$", "AnyViewer",
action_process_image_name ~= "(?i)^(jumpconnect|jump desktop connect)([.]exe)?$", "JumpConnect",
action_process_signature_vendor = "Zhou Huabing", "RustDesk",
action_process_signature_vendor = "FleetDeck Inc", "FleetDeck",
action_process_signature_vendor = "SimpleHelp Ltd", "SimpleHelp",
action_process_signature_vendor = "NetSupport Ltd", "NetSupport",
action_process_signature_vendor = "Atera Networks", "Atera",
action_process_signature_vendor = "Splashtop Inc", "Splashtop",
action_process_signature_vendor in ("ConnectWise, LLC", "ConnectWise, Inc."), "ScreenConnect",
action_file_path ~= "(?i)(inomeogfingihgjfjlpeplalcfajhgai|gbchcmhmhahfdphkhkmpfmihenigjmpp)", "Chrome Remote Desktop",
"")
| filter product != ""
| alter signal = if(signal = "", "product-seen", signal)
| comp count_distinct(product) as product_count, values(product) as products, values(signal) as signals, min(_time) as first_seen, max(_time) as last_seen by agent_hostname
| alter escalate = if(product_count >= 4, "yes", "no")
| sort desc product_count
Lower-fidelity parts (1)
- the Quick Assist branch — Quick Assist ships with Windows and is routine in support sessions. Remove: delete the // optional comment and the line under it
osquery
Written for this site, from indicators reported by Mandiant, Unit 42, MicrosoftLocal inventory of running clients and installed macOS bundles; four or more distinct products on one device is the DTEX threshold.
-- Hunt: unmanaged remote-access and RMM tooling, running now (Windows and macOS) or installed as a macOS bundle.
SELECT 'running' AS signal, name AS detail, path
FROM processes
WHERE lower(replace(name, '.exe', '')) IN (
'anydesk',
'teamviewer',
'teamviewer_service',
'tv_w32',
'tv_x64',
'rustdesk',
'remoting_host',
'srservice',
'srmanager',
'splashtopstreamer',
'splashtop streamer',
'meshagent',
'ateraagent',
'client32',
'pcilic',
'pcideply',
'screenconnect.clientservice',
'connectwisecontrol.client',
'screenconnect client',
'g2comm',
'gotoassist',
'lmiguardiansvc',
'lmi_rescue',
'aeroadmin',
'dwrcs',
'supremo',
'winvnc',
'tvnserver',
-- optional: Quick Assist ships with Windows and is routine in support sessions
'quickassist',
'fleetdeck_agent',
'simplehelpcustomer',
'zohoassist',
'action1_agent',
'nomachine',
'anyviewer',
'jumpconnect',
'jump desktop connect'
)
UNION ALL
SELECT 'installed-bundle', filename, path
FROM file
WHERE path IN ('/Applications/AnyDesk.app', '/Applications/TeamViewer.app', '/Applications/RustDesk.app',
'/Applications/Splashtop Streamer.app', '/Applications/ScreenConnect Client.app',
'/Applications/AnyViewer.app', '/Applications/Jump Desktop Connect.app')
Lower-fidelity parts (1)
- the quickassist entry — Quick Assist ships with Windows and is routine in support sessions. Remove: delete the -- optional comment and the 'quickassist' line under it
YARA
Written for this site, from indicators reported by ZscalerRun over AnyDesk's service.conf or user.conf; unattended access is a legitimate setting, so the config-edit match in the other queries is what separates tampering.
rule AnyDesk_Unattended_Access_Config
{
meta:
description = "AnyDesk configuration carrying the password hash, password salt and token salt operators write to enable unattended access"
reference = "https://www.zscaler.com/blogs/security-research/pyongyang-your-payroll-rise-north-korean-remote-workers-west"
strings:
$hash = "pwd_hash" ascii
$salt = "pwd_salt" ascii
$token = "token_salt" ascii
condition:
filesize < 64KB and all of them
}
False positives and tuning
Most of this software is legitimate, and in managed-service environments several agents are the support tooling. Run this as an inventory sweep first and alert only on what your own IT function does not deploy.
Scope to devices issued in the last ninety days and correlate whether the tool arrived before or after the endpoint agent. The process lists are not exhaustive and executable names change between versions.
IT support staff, managed-service technicians and solutions engineers legitimately accumulate remote-access tools. Exclude those roles before running the counting queries rather than raising the threshold, which discards the cases DTEX describes.
On macOS, an MDM-deployed remote-support client appears in the same application and launchd locations as an unsanctioned one, so compare against the management inventory.
Sources
- Global Companies Are Unknowingly Paying North Koreans: Here's How to Catch Them — Unit 42 (Palo Alto Networks), 2024-11-13
- Staying a Step Ahead: Mitigating the DPRK IT Worker Threat — Google Cloud (Mandiant), 2024-09-23
- Threat Spotlight: Red Flags for Red Star Hackers: Hunting for North Korean Insiders — ReliaQuest, 2025-05-08
- Jasper Sleet: North Korean remote IT workers' evolving tactics to infiltrate organizations — Microsoft Security Blog, 2025-06-30
- i3 Threat Advisory: Identifying North Korean IT Workers: Key Threat Indicators — DTEX Systems, 2025-05-14
- Famous Chollima Threat Actor Profile — Huntress Threat Library
- Pyongyang in Your Payroll: The Rise of North Korean Remote Workers in the West — Zscaler ThreatLabz, 2025-07-15