Every major operating system can run a program at a set time or at startup. That is useful for administrators and equally useful to someone who has gained a foothold. MITRE tracks this as Scheduled Task/Job (T1053), under three tactics: Execution, Persistence and Privilege Escalation.
The platform list is wide: Containers, ESXi, Linux, macOS, Network Devices and Windows. The technique has five sub-techniques, covered separately: at, cron, Windows Scheduled Task, systemd timers and container orchestration jobs. This post covers what they share.
How attackers use it
MITRE describes three broad uses.
First, initial or recurring execution. A scheduled task can run malicious code once at a chosen time, or repeatedly. Utilities for this exist in all major operating systems.
Second, persistence. Tasks can be set to run at system startup or on a schedule, so access survives a reboot or a logoff.
Third, running under a chosen context. A task can run as a specified account, such as one with elevated privileges. A task can also be scheduled on a remote system when the proper authentication is met. On Windows that typically relies on RPC and file and printer sharing, and it usually requires membership in an admin or otherwise privileged group on the remote system.
MITRE adds one more point. Similar to System Binary Proxy Execution, scheduling can mask a one time execution under a trusted system process. The thing that starts your code is the scheduler, not an obviously strange binary.
The procedure examples on the MITRE page include network device scheduled tasks configured to run CLI scripts weekly, which is a useful reminder that this is not only a server and laptop concern.
How to detect it
MITRE's detection strategy has one analytic per platform family.
- Windows: creation or modification of tasks using schtasks.exe, at.exe or COM objects, followed by execution of outlier processes tied to the scheduled job.
- Linux: creation or modification of cron jobs through crontab, the /etc/cron.* directories or systemd timer units, with execution by unusual users or at non standard intervals.
- macOS: creation or alteration of LaunchAgents or LaunchDaemons, with the matching plist modification followed by execution of the associated binary.
- Containers: unusual use of cron or sleep loops inside containers that execute unfamiliar scripts or binaries repeatedly.
- ESXi: modification of cron jobs, local.sh scripts or scheduled API calls used to persist custom binaries or shell scripts.
The common structure is a change event followed by an execution event. Either alone is noisy. Together, especially when the creator is unusual or the interval is odd, they stand out.
Useful questions to put to your logs:
- Who created this task, and from which host or session?
- Does the program it runs live somewhere writable by ordinary users?
- Is the schedule new, or does it match a change ticket?
- Does it run as SYSTEM or root when it does not need to?
How to reduce the risk
MITRE lists five mitigations for the parent technique.
- User account management. Limit privileges of user accounts and remediate privilege escalation vectors so only authorized administrators can create scheduled tasks on remote systems.
- Operating system configuration. Configure scheduled tasks to run under the authenticated account instead of SYSTEM. The related registry key is HKLM\SYSTEM\CurrentControlSet\Control\Lsa\SubmitControl, and the Group Policy setting is Domain Controller: Allow server operators to schedule tasks, set to disabled.
- Restrict file and directory permissions. Set permissions that are not specific to users or privileged accounts, so ordinary users cannot edit the scripts that tasks run.
- Privileged account management. Allow only the Administrators group the Increase scheduling priority right.
- Audit. Explore systems for permission weaknesses in scheduled tasks that could be used to escalate privileges.
Check your own environment
A short inventory beats a long policy. Read-only commands per platform:
- Windows PowerShell:
Get-ScheduledTask | Where-Object State -ne 'Disabled'lists active tasks. - Windows Command Prompt:
schtasks /query /fo LIST /vgives full detail for each task. - Linux shell:
crontab -lfor the current user, andls -la /etc/cron.d /etc/cron.daily /etc/cron.hourlyfor system jobs. - Linux shell:
systemctl list-timers --allfor systemd timers. - Kubernetes with kubectl:
kubectl get cronjobs --all-namespaces.
For each result, note the owner, the account it runs as and the file path of the program. Then check the file permissions on that path. A task that runs a script anyone can edit is a privilege escalation waiting to happen.
Do not forget what the task pulls in. Scheduled jobs that fetch packages or container images inherit the trust problems of those dependencies. The free in-browser dependency scan at gold.safeguard.sh/scan needs no login, keeps your file on your machine and covers up to 100 dependencies, which makes it a quick way to review what a recurring job installs.
Quick check
What two events make up the common detection pattern?
A creation or modification of a scheduled task or job, followed by execution of an unusual process, user or interval tied to it.
Why can scheduling help an attacker evade defenses?
The code can run under a trusted system process, so a one time execution is masked beneath the scheduler.
Which mitigation keeps remote task creation under control?
User account management: limit privileges and fix escalation paths so only authorized administrators can create scheduled tasks on remote systems.
Sources
- MITRE ATT&CK: Scheduled Task/Job (T1053)