Home / Blog / Threat Hunting

Advanced Threat Hunting

How to Hunt for Hidden Scheduled Tasks on Windows Servers

Find scheduled tasks hidden by deleting their SD registry value, as seen with Tarrask, using registry telemetry, Task Scheduler logs and a read only estate sweep.

Scheduled tasks are one of the most common ways attackers keep access to Windows systems, and most SOCs already alert on new ones. A nation state technique first described by Microsoft in 2022 goes a step further: it deletes a single registry value so the task vanishes from Task Scheduler and schtasks /query while it keeps running. This guide is for threat hunters in government and the wider public sector who need to find these hidden tasks on servers that rarely reboot, without breaking change control.

TechniquesT1053.005 Scheduled Task, T1564 Hide Artifacts
Key telemetryRegistry deletes under TaskCache\Tree, Task Scheduler logs
Best targetsDomain controllers, internet facing and long uptime servers
>

Scenario: An NCSC co-sealed advisory describes a China based actor using hidden scheduled tasks to re-establish command and control from internet facing servers. Your department runs a web application server, APP-SRV-07, that has not rebooted in 140 days. The security lead asks whether any server in your estate has a task that the normal tools cannot see. You have Defender for Endpoint on most servers, Sysmon on the rest and a hunting window that does not allow you to change anything on production systems.

Understand how a task is hidden

When Windows registers a scheduled task, it writes the task in three places. Knowing all three is what makes this hunt possible, because the attacker usually only removes one piece.

Tree keyHKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\TASK_NAME holds the Id, Index and SD values.
Tasks keyHKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{GUID} holds Actions, Path and Triggers, mapped by the Id value.
XML fileAn extensionless file named after the task in C:\Windows\System32\Tasks, which also records the command it runs.

The SD value is the task's security descriptor, which controls who can see and run it. Microsoft reported that the Tarrask malware, used by the actor then tracked as HAFNIUM and now named Silk Typhoon, created a task called WinUpdate and then deleted its SD value. With SD gone, the task disappeared from Task Scheduler and schtasks /query but still ran on its triggers.

Deleting SD fails with Access Denied even from an elevated prompt. It must run as SYSTEM, which in that case the malware achieved by stealing a token from lsass.exe. MITRE ATT&CK records this under T1053.005 and links it to T1564 Hide Artifacts, and also notes that attackers may hide tasks by altering other metadata such as the Index value.

i

Note: Microsoft also observed that an attacker could delete the Tree key, the Tasks key and the XML file entirely. The task would then keep running until the next reboot or until the Task Scheduler service process stopped. That leaves almost no disk artefacts, which is why process telemetry matters in the later tasks.

Check your telemetry before you hunt

A hunt with blind spots produces false confidence. Before you query anything, confirm which of these sources you actually collect for your target servers, and record the gaps in your hunt plan.

SourceWhat it gives youDefault state
Defender for Endpoint DeviceRegistryEventsRegistry value deletes and changes, with the initiating process and accountOn when onboarded
Sysmon Event ID 12 and 13Registry object create and delete (12) and value set (13)Depends on your Sysmon config including TaskCache paths
Security Event ID 4657Registry value modified or deletedOnly with object access auditing and a SACL on the key
Security Event ID 4698 to 4702Task created, deleted, enabled, disabled and updatedNeeds Audit Other Object Access Events
TaskScheduler Operational log106 registered, 140 updated, 141 deleted, 200 action started, 201 action completedOften disabled, must be enabled
!

Watch out: Microsoft notes that neither Security Event ID 4698 nor the TaskScheduler Operational log is turned on by default. If either is missing on your servers, raise it through your normal change process as a protective monitoring improvement. Do not enable logging during the hunt on a production system without an approved change.

Hunt for SD value deletion

The strongest single signal is a delete of a value named SD under the TaskCache Tree key. Legitimate software almost never does this, so even one hit deserves investigation.

Defender for Endpoint

Defender XDR advanced huntingKQL
DeviceRegistryEvents
| where Timestamp > ago(30d)
| where ActionType == "RegistryValueDeleted"
| where RegistryKey has @"\Schedule\TaskCache\Tree\"
| where RegistryValueName == "SD"
| extend TaskName = tostring(split(RegistryKey, @"\TaskCache\Tree\")[1])
| project Timestamp, DeviceName, TaskName, RegistryKey,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessAccountName, InitiatingProcessAccountSid
| order by Timestamp desc

Splunk with Sysmon

SplunkSPL
index=sysmon EventCode=12 EventType=DeleteValue
TargetObject="*\\Schedule\\TaskCache\\Tree\\*\\SD"
| table _time host Image User TargetObject
| sort - _time

Sigma rule for wider coverage

SigmaYAML
title: Scheduled Task Hidden by SD Value Deletion
status: experimental
description: Detects deletion of the SD value of a scheduled task, which hides it from Task Scheduler and schtasks.
references:
    - https://attack.mitre.org/techniques/T1053/005/
tags:
    - attack.persistence
    - attack.defense-evasion
    - attack.t1053.005
    - attack.t1564
logsource:
    product: windows
    category: registry_delete
detection:
    selection:
        EventType: DeleteValue
        TargetObject|contains: '\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\'
        TargetObject|endswith: '\SD'
    condition: selection
falsepositives:
    - Unknown
level: high

Extend the same hunt to look for changes to the Index value under the Tree key by any process other than the Task Scheduler service. Expect some noise here, so baseline it per server role before turning it into a detection.

+

Tip: Because the delete must run as SYSTEM, pivot from any hit into evidence of how SYSTEM was reached. Look for process access to lsass.exe, new services or unusual parent processes around the same time on that host.

Sweep servers for tasks with no SD value

Telemetry only covers the period you have retained. A task hidden two years ago on a server that never reboots will not appear in 30 days of registry events. A read only sweep of the registry closes that gap.

The script below lists every task key under Tree that has an Id value but no SD value. It reads the registry and writes nothing. Run it elevated, through your approved remote tooling such as Defender for Endpoint Live Response or your server management platform, under the change or hunt authorisation your department requires.

Windows PowerShell, read onlyPowerShell
$tree = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree'
Get-ChildItem -Path $tree -Recurse -ErrorAction SilentlyContinue |
    Where-Object {
        $names = $_.GetValueNames()
        ($names -contains 'Id') -and ($names -notcontains 'SD')
    } |
    ForEach-Object {
        [PSCustomObject]@{
            Host    = $env:COMPUTERNAME
            TaskKey = $_.Name
            TaskId  = $_.GetValue('Id')
        }
    }

For each result, use the TaskId to open the matching key under TaskCache\Tasks and read the Actions value, then compare it with the XML file of the same name in C:\Windows\System32\Tasks. Keys that the script cannot read are worth recording too, as they may point to tampered permissions.

Find tasks that run but cannot be seen

A hidden task still has to execute. Programs launched by a task usually start under the svchost.exe instance that hosts the Schedule service. Hunting rare children of that process catches hidden tasks even when the registry artefacts are gone.

Defender XDR advanced huntingKQL
DeviceProcessEvents
| where Timestamp > ago(30d)
| where InitiatingProcessFileName =~ "svchost.exe"
| where InitiatingProcessCommandLine has "Schedule"
| where not(FolderPath startswith @"C:\Windows\")
      and not(FolderPath startswith @"C:\Program Files")
| summarize Devices = dcount(DeviceName), Runs = count(),
            FirstSeen = min(Timestamp), LastSeen = max(Timestamp),
            SampleCmd = any(ProcessCommandLine)
    by FileName, FolderPath, SHA256
| where Devices <= 2
| order by Runs desc

Then join what runs with what is visible. For any suspicious binary, check whether a TaskScheduler Operational Event ID 200 on that host names a task that no longer appears in Task Scheduler. A task that keeps producing 200 and 201 events but is missing from schtasks /query is exactly what this hunt is looking for.

Microsoft's own guidance also stresses outbound traffic. Hidden tasks in the Tarrask case were used to restore command and control connections, so review regular outbound connections from Tier 0 and Tier 1 servers to destinations they have never contacted before.

Triage findings and report them

Treat each finding as a possible nation state foothold. Collect evidence before you change anything, and follow your department's incident process for containment.

Task with SD deleted

High
Indicator

Registry delete of SD under TaskCache\Tree, or a sweep result showing a task key with Id but no SD.

Response

Preserve the Tree and Tasks keys, the XML file and the binary named in Actions. Escalate as a suspected intrusion and report through your incident route, which may include the NCSC.

Rare child of the Schedule service

Medium
Indicator

A binary outside system paths launched by the Schedule service on one or two servers only.

Response

Check signer, hash reputation and whether a visible task explains it. If none does, collect the file and escalate.

Index value changed

Medium
Indicator

A process other than the Task Scheduler service writing the Index value under TaskCache\Tree.

Response

Compare with the server's baseline and the change record. Unexplained changes go to deeper investigation.

  • Record the hunt hypothesis, scope, data sources and retention period used.
  • List servers you could not sweep or that lacked registry telemetry.
  • Map findings to T1053.005 and T1564 in the hunt report.
  • Raise change requests for missing logging: TaskScheduler Operational, 4698 auditing, Sysmon TaskCache coverage.
  • Turn the SD deletion query into a scheduled detection through your rule approval process.
  • Reference the hunt as evidence for Cyber Assessment Framework objective C, principles C1 Security Monitoring and C2 Proactive Security Event Discovery.

Key takeaways

  1. Deleting a task's SD value hides it from Task Scheduler and schtasks while it keeps running.
  2. The delete needs SYSTEM rights, so a hit also points to privilege escalation on that host.
  3. Hunt registry deletes of SD under TaskCache\Tree in DeviceRegistryEvents, Sysmon Event ID 12 or Security Event ID 4657.
  4. Sweep long uptime servers read only for task keys with an Id but no SD, because telemetry retention will not cover old implants.
  5. Rare children of the Schedule service catch hidden tasks even when the registry artefacts have been removed.

Hidden scheduled tasks reward patience more than clever tooling. Run the registry sweep on your most critical servers first, close the logging gaps through change control, and keep the SD deletion rule live so the next attempt is caught on the day it happens rather than months later.

Written by Freya, Senior SOC Analyst, Government

Keep going

More in Threat Hunting

IntermediateThreat Hunting

How to Hunt for C2 Beaconing in Proxy and EDR Logs

Find regular callback traffic in proxy and EDR logs with interval analysis in KQL and SPL, then separate real command and control from noisy legitimate software.

5 Nov 20269 min read