Anti-Idle and Mouse-Jiggling Tooling on Employee Endpoints
WindowsmacOS
TTP Hunt low DPRK IT Worker FraudLaptop Farm
Software that keeps a machine awake and an account showing as present, which is what an operator running several jobs at once needs on every laptop they are not currently at.
What this hunt looks for
An operator holding four jobs cannot be at four keyboards. Mandiant records Caffeine used to remain active across several laptops and profiles; DTEX names caffeine.exe on Windows and owly on macOS; ReliaQuest notes IP-KVM hardware provides mouse-jiggling as a built-in feature, which is one reason the hardware is attractive.
The tooling is trivially available and the behaviour is not itself malicious, so what makes this hunt worth running is not the presence of the tool but the picture it completes: presence indicators that stay green through hours where nothing else on the device happens.
- Technique
- Defence evasion of presence and idle-detection controls, supporting concurrent fraudulent employment (MITRE ATT&CK T1078).
- Data sources
- EDR process telemetry
- 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 | Caffeine (caffeine.exe) |
Named by Mandiant as used to remain active across several laptops and profiles; DTEX names the same executable. |
| Software | owly |
macOS anti-screen-lock tool named by DTEX. |
| Command | caffeinate (any flags, for example -d) |
Built-in macOS utility that prevents display sleep; the no-install equivalent of the above. |
Logic
Every query below implements these steps, so the same hunt returns the same result in each product.
- Collect: process starts on Windows and macOS endpoints, last 90 days
- Match: image is an anti-idle tool (Caffeine, MouseJiggler, MoveMouse, owly) or a common keep-awake tool (caffeinate, Amphetamine)
- Report: devices and users with matches on 5 or more distinct days, most days first
Queries
Defender / Sentinel KQL
Written for this siteDevices and accounts that ran an anti-idle tool on five or more distinct days in the last 90 days.
let AntiIdleTools = dynamic(["caffeine.exe", "caffeine64.exe", "mousejiggler.exe", "movemouse.exe", "owly"]);
// optional: keep-awake tools that developers and presenters also run
let CommonKeepAwake = dynamic(["PowerToys.Awake.exe", "caffeinate", "Amphetamine", "KeepingYouAwake"]);
DeviceProcessEvents
| where Timestamp > ago(90d)
| where FileName in~ (AntiIdleTools)
// optional: keep-awake tools that developers and presenters also run
or FileName in~ (CommonKeepAwake)
| summarize Executions = count(), ActiveDays = dcount(bin(Timestamp, 1d)),
Tools = make_set(FileName), LastSeen = max(Timestamp)
by DeviceName, AccountName
| where ActiveDays >= 5
| sort by ActiveDays desc
Lower-fidelity parts (1)
- the PowerToys Awake, caffeinate, Amphetamine and KeepingYouAwake entries — built-in or mainstream keep-awake tools that developers, presenters and people on long transfers run for good reasons. Remove: Delete both lines beginning // optional:, the let CommonKeepAwake line below the first, and the or FileName in~ (CommonKeepAwake) line below the second.
Splunk SPL
Written for this siteHosts and users that ran an anti-idle tool on five or more distinct days in the last 90 days.
```sourcetype placeholders: index=endpoint with Sysmon or EDR process events (process_name, host, user)```
```optional: the second IN list is keep-awake tools that developers and presenters also run```
index=endpoint earliest=-90d (process_name IN ("caffeine.exe", "caffeine64.exe", "mousejiggler.exe", "movemouse.exe", "owly") OR process_name IN ("PowerToys.Awake.exe", "caffeinate", "Amphetamine", "KeepingYouAwake"))
| eval day=strftime(_time, "%Y-%m-%d")
| stats count AS executions dc(day) AS active_days values(process_name) AS tools max(_time) AS last_seen BY host, user
| where active_days>=5
| sort 0 - active_days
| convert ctime(last_seen)
Lower-fidelity parts (1)
- the PowerToys Awake, caffeinate, Amphetamine and KeepingYouAwake entries — built-in or mainstream keep-awake tools that developers, presenters and people on long transfers run for good reasons. Remove: Delete the optional comment and, on the index line, the text OR process_name IN ("PowerToys.Awake.exe", ...) up to the closing parenthesis of the group.
Sigma
Written for this siteA single execution of an anti-idle or keep-awake tool, meant to be counted per device by the SIEM.
title: Anti-Idle or Mouse-Jiggling Utility Executed on an Employee Endpoint
id: c3a7f0b4-92d1-4e58-8a36-5d1b7e90f2a6
status: experimental
description: >
Detects utilities whose only function is to keep a host awake and an account
showing as present. Mandiant reports Caffeine used by DPRK IT workers to
remain active across several laptops and profiles simultaneously; DTEX names
caffeine.exe on Windows and owly on macOS. One execution is ordinary; report
devices that run one on five or more distinct days.
references:
- https://cloud.google.com/blog/topics/threat-intelligence/mitigating-dprk-it-worker-threat
- https://www.dtex.ai/resources/i3-threat-advisory-inside-the-dprk/
logsource:
category: process_creation
detection:
selection_anti_idle:
Image|endswith:
- '\caffeine.exe'
- '\caffeine64.exe'
- '\MouseJiggler.exe'
- '\MoveMouse.exe'
- '/owly'
# optional: keep-awake tools that developers and presenters also run
selection_common:
Image|endswith:
- '\PowerToys.Awake.exe'
- '/caffeinate'
- '/Amphetamine'
- '/KeepingYouAwake'
condition: 1 of selection_*
falsepositives:
- Users running long builds, renders, transfers or presentations who do not want the screen to lock
level: low
Lower-fidelity parts (1)
- the PowerToys Awake, caffeinate, Amphetamine and KeepingYouAwake entries — built-in or mainstream keep-awake tools that developers, presenters and people on long transfers run for good reasons. Remove: Delete the # optional: line and selection_common with its list, and change the condition to selection_anti_idle.
Elastic
Written for this siteHosts and users that ran an anti-idle tool on five or more distinct days in the last 90 days.
FROM logs-endpoint.events.process-*
| WHERE @timestamp > NOW() - 90 days
| EVAL tool = TO_LOWER(process.name)
| WHERE tool IN ("caffeine.exe", "caffeine64.exe", "mousejiggler.exe", "movemouse.exe", "owly") OR tool IN ("powertoys.awake.exe", "caffeinate", "amphetamine", "keepingyouawake")
| EVAL day = DATE_TRUNC(1 day, @timestamp)
| STATS executions = COUNT(*), active_days = COUNT_DISTINCT(day), tools = VALUES(process.name), last_seen = MAX(@timestamp) BY host.name, user.name
| WHERE active_days >= 5
| SORT active_days DESC
| LIMIT 200
Lower-fidelity parts (1)
- the PowerToys Awake, caffeinate, Amphetamine and KeepingYouAwake entries — built-in or mainstream keep-awake tools that developers, presenters and people on long transfers run for good reasons. Remove: Delete OR tool IN ("powertoys.awake.exe", ...) from the second WHERE line.
CrowdStrike LogScale
Written for this siteDevices and users that ran an anti-idle tool on five or more distinct days in the last 90 days.
#event_simpleName=ProcessRollup2
| in(field=FileName, values=["caffeine.exe", "caffeine64.exe", "mousejiggler.exe", "movemouse.exe", "owly"], ignoreCase=true)
// optional: keep-awake tools that developers and presenters also run
or in(field=FileName, values=["PowerToys.Awake.exe", "caffeinate", "Amphetamine", "KeepingYouAwake"], ignoreCase=true)
| formatTime("%Y-%m-%d", field=@timestamp, as=day)
| groupBy([aid, ComputerName, UserName], function=[count(as=executions), count(day, distinct=true, as=active_days), collect(FileName), max(@timestamp, as=last_seen)])
| active_days >= 5
| sort(active_days, order=desc)
Lower-fidelity parts (1)
- the PowerToys Awake, caffeinate, Amphetamine and KeepingYouAwake entries — built-in or mainstream keep-awake tools that developers, presenters and people on long transfers run for good reasons. Remove: Delete the line beginning // optional: and the or in(...) line after it.
Cortex XQL
Written for this siteHosts and users that ran an anti-idle tool on five or more distinct days in the last 90 days.
dataset = xdr_data
| filter event_type = ENUM.PROCESS
| alter tool = lowercase(action_process_image_name)
| filter tool in ("caffeine.exe", "caffeine64.exe", "mousejiggler.exe", "movemouse.exe", "owly")
// optional: keep-awake tools that developers and presenters also run
or tool in ("powertoys.awake.exe", "caffeinate", "amphetamine", "keepingyouawake")
| bin _time span = 1d
| comp count() as executions, count_distinct(_time) as active_days, values(tool) as tools by agent_hostname, actor_effective_username
| filter active_days >= 5
| sort desc active_days
Lower-fidelity parts (1)
- the PowerToys Awake, caffeinate, Amphetamine and KeepingYouAwake entries — built-in or mainstream keep-awake tools that developers, presenters and people on long transfers run for good reasons. Remove: Delete the line beginning // optional: and the or tool in (...) line after it.
osquery
Written for this siteAnti-idle and keep-awake processes running now, on Windows or macOS, as a point-in-time check without process telemetry.
SELECT name, path, cmdline, uid
FROM processes
WHERE lower(name) IN ('caffeine.exe', 'caffeine64.exe', 'mousejiggler.exe', 'movemouse.exe', 'owly')
-- optional: keep-awake tools that developers and presenters also run
OR lower(name) IN ('powertoys.awake.exe', 'caffeinate', 'amphetamine', 'keepingyouawake');
Lower-fidelity parts (1)
- the PowerToys Awake, caffeinate, Amphetamine and KeepingYouAwake entries — built-in or mainstream keep-awake tools that developers, presenters and people on long transfers run for good reasons. Remove: Delete the -- optional: line and the OR lower(name) IN (...) line after it, then end the line above with a semicolon.
False positives and tuning
Keeping a machine awake is ordinary: long builds, transfers, rendering and presenting all produce it. Treat this as one column in an insider-risk review beside session length and working hours, not as an alert.
Note the significant blind spot ReliaQuest identifies: an IP-KVM performs mouse jiggling in hardware, so the operators furthest along in their tradecraft leave no software artifact for this hunt to find at all.
Sources
- Staying a Step Ahead: Mitigating the DPRK IT Worker Threat — Google Cloud (Mandiant), 2024-09-23
- i3 Threat Advisory: Identifying North Korean IT Workers: Key Threat Indicators — DTEX Systems, 2025-05-14
- Threat Spotlight: Red Flags for Red Star Hackers: Hunting for North Korean Insiders — ReliaQuest, 2025-05-08