Forensics · Lesson 11

Scheduled Tasks, Cron & Persistence Clues

Learn how Windows Scheduled Tasks, Linux cron jobs, and systemd timers create recurring or triggered execution, how to inspect them safely, and how to connect configuration to actual process activity.

Scheduled execution is common in legitimate systems. Identify the trigger, action, account, linked files, and execution evidence before deciding whether an item belongs.

Lesson Snapshot

WindowsScheduled Tasks
Linuxcron + timers
Key distinctionConfigured vs executed
GoalExplain recurrence

Learning objectives

Connect scheduled configuration to real execution

01

Explain how scheduled execution can create persistence without a continuously running process.

02

Recognize Windows Scheduled Tasks, Linux cron, and systemd timers as different scheduling mechanisms.

03

Inspect triggers, commands, users, arguments, working directories, and execution history before changing scheduled items.

04

Distinguish legitimate automation from suspicious persistence using scenario context and corroborating evidence.

05

Correlate scheduled activity with processes, files, logs, network connections, and account evidence.

06

Preserve task and timer evidence before disabling, deleting, or editing configuration.

Core idea

Scheduling explains recurrence, not intent

The schedule tells you when execution should happen. The action, user, path, logs, and process evidence explain what actually happened.

Competition caution

Preserve the scheduler entry before removing it

Record trigger, action, arguments, user, linked script or executable, and execution history before disabling or deleting the item.

Persistence principles

Use scheduler evidence without overclaiming

Persistence is a mechanism, not a verdict

Scheduled tasks, cron jobs, and timers are used by legitimate software and administrators. Their presence alone does not prove malicious activity.

Trigger and action belong together

The trigger explains when execution should occur. The action explains what actually runs.

User context changes meaning

SYSTEM, root, service accounts, and normal users have different privilege and access implications.

Paths provide context

Recurring execution from Program Files or /usr differs from recurring execution from Downloads, Temp, AppData, /tmp, or a hidden user directory.

Configured is not the same as executed

Use scheduler history, logs, process evidence, output files, or network activity to prove actual execution.

Preserve before cleanup

Deleting a scheduler entry can remove the trigger, command, account, arguments, and history needed for a forensic answer.

Evidence fields

Preserve the configuration that explains execution

Name

Identifies the task, cron entry, timer, or related unit.

Trigger / schedule

Explains when or under what condition execution occurs.

Action / command

Shows the executable, script, or command that actually runs.

Arguments

Can reveal script paths, configuration files, or targets.

Run-as user

Explains account and privilege context.

Working directory

Can affect relative paths and loaded files.

Enabled state

Shows whether future execution is currently permitted.

Last / next run

Adds timeline context where available.

History / logs

Helps prove whether execution actually occurred.

Windows Scheduled Tasks

Understand common triggers and actions

At logon

Runs when a selected user or any user signs in.

At startup

Runs when Windows starts.

Time-based

Runs once or repeatedly according to a schedule.

On event

Runs when a selected Windows event condition occurs.

Action

Usually starts a program or command with optional arguments.

Principal

Defines which account and privilege context the task uses.

List scheduled tasks

Get-ScheduledTask

Shows task names, paths, states, and basic configuration.

Inspect one task

Get-ScheduledTask -TaskName "ExampleTask" | Format-List *

Shows detailed configuration for one task.

Runtime information

Get-ScheduledTaskInfo -TaskName "ExampleTask"

Shows last run time, next run time, and last result where available.

Actions and triggers

(Get-ScheduledTask -TaskName "ExampleTask").Actions
(Get-ScheduledTask -TaskName "ExampleTask").Triggers

Displays what runs and when.

Full XML definition

Export-ScheduledTask -TaskName "ExampleTask"

Shows the full task definition for deeper evidence review.

Task Scheduler operational events

Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" -MaxEvents 50

Reads recent Task Scheduler operational events when that channel is enabled.

Windows execution history

Prove whether the task actually ran

Task configuration

Task name, trigger, action, arguments, account, conditions, and settings.

Task Scheduler Operational log

Registration, trigger, launch, completion, and failure evidence when enabled.

Process evidence

Can prove that the configured executable or script actually ran.

File metadata

Can show when the linked script or executable was created or modified.

Network evidence

Can connect the launched process to listening or outbound activity.

Linux cron

Know the main cron configuration locations

User crontab

crontab -l

Schedules commands under one user's context.

/etc/crontab

/etc/crontab

System-wide cron configuration that explicitly includes a user field.

/etc/cron.d

/etc/cron.d/*

Package or administrator-defined system cron jobs.

Periodic directories

/etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly

Scripts executed on periodic schedules according to system configuration.

0 2 * * *

Runs daily at 02:00.

*/15 * * * *

Runs every 15 minutes.

0 9 * * 1-5

Runs at 09:00 Monday through Friday.

@reboot

Runs after cron starts following reboot on implementations supporting this form.

Current user's crontab

crontab -l

Displays the current user's cron jobs.

Another user's crontab

sudo crontab -u trainee1 -l

Displays the selected user's cron jobs where authorized.

System crontab

sudo cat /etc/crontab

Shows system-wide cron entries.

Cron.d inventory

sudo ls -la /etc/cron.d

Lists cron definitions stored in /etc/cron.d.

Periodic directories

sudo ls -la /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly

Shows common periodic script locations.

Search cron logs

grep -i "cron" /var/log/syslog

Finds cron-related messages on systems that log cron activity to syslog.

systemd timers

Treat timer and service as a pair

Timer unit

Defines when activation occurs.

Service unit

Defines what command actually runs.

OnCalendar

Provides calendar-style scheduling.

OnBootSec / OnUnitActiveSec

Provides relative scheduling based on boot or prior activation.

Persistent

Can cause missed calendar runs to be triggered later when configured.

Enablement

Determines whether the timer activates automatically.

List timers

systemctl list-timers --all

Shows timer units, next run, last run, and associated units.

Inspect timer

systemctl status example.timer

Shows current state and recent records.

Timer definition

systemctl cat example.timer

Displays the timer unit file and drop-ins.

Linked service

systemctl cat example.service

Shows what command the timer ultimately launches.

Timer journal

journalctl -u example.timer

Shows timer-unit journal records.

Service journal

journalctl -u example.service

Shows execution records for the linked service.

Reasoning

Separate configured behavior from observed execution

Task runs at logon

Supported

The task is configured to launch when its logon condition is met.

Not supported

The task definitely executed during every login.

Cron uses */15 * * * *

Supported

The command is configured for execution every 15 minutes.

Not supported

The command successfully ran every 15 minutes.

systemd timer is enabled

Supported

The timer is configured for automatic activation according to its unit definition.

Not supported

The linked service is currently running.

Task runs as SYSTEM or cron runs as root

Supported

The scheduled action executes with a highly privileged account when triggered.

Not supported

The scheduled item is malicious.

Action points to AppData or /tmp

Supported

The scheduler launches a user-profile or temporary-location file.

Not supported

The file is malicious without further evidence.

History shows repeated launches

Supported

The scheduler recorded multiple executions.

Not supported

Every run completed successfully unless result evidence confirms that.

Path triage

The scheduled command path changes the investigation

Program Files / /usr / vendor path

Is the executable part of installed or required software?

AppData / ~/.config / ~/.local

Is this normal per-user application behavior or an unexpected startup location?

Temp / /tmp

Why is recurring execution tied to temporary storage?

Downloads / Documents

Was the file downloaded or manually placed before scheduling?

ProgramData / /opt

Does software installation or package history explain the file?

Hidden user directory

Is this ordinary application configuration or something unexpected?

Question-to-evidence map

Use the right artifact for the right scheduling question

What runs?

Task action, cron command, systemd service ExecStart.

When does it run?

Task trigger, cron schedule, timer OnCalendar or relative timing settings.

Who runs it?

Task principal, cron owner or user field, systemd User= setting.

Did it actually run?

Task history, cron/syslog, journal, process evidence, file output, or network activity.

Was it added recently?

Task-registration events, file timestamps, unit metadata, administrative logs, or package activity.

Is it required?

Scenario requirements, dependencies, package/vendor context, and business purpose.

Preserve before action

Capture scheduler state before disabling it

Windows Scheduled Task

Task name/path, triggers, actions, arguments, working directory, run-as account, enabled state, last/next run, XML, and history.

User cron job

User, exact schedule, command, crontab contents, linked files, and execution logs.

System cron job

File path, schedule, user field, command, ownership, permissions, timestamps, package source, and execution logs.

systemd timer

Timer name, schedule, enablement, linked service, unit paths, ExecStart, User, journal records, and last/next activation.

Correlation

Connect scheduler configuration to actual activity

Task registered at 09:00 + task starts at 09:05 + powershell.exe parent + helper.exe child

Supported conclusion

The scheduled task likely explains the PowerShell and helper.exe execution chain.

Cron entry every 10 minutes + syslog CRON record + script process at matching time

Supported conclusion

The cron job likely launched the observed script process.

systemd timer activates + linked service starts + process opens outbound connection

Supported conclusion

The timer-service chain likely explains the network-active process.

Downloaded script at 11:12 + task created at 11:15 pointing to script + first run at 11:20

Supported conclusion

The download, registration, and scheduled execution form a coherent sequence.

Package install + /etc/cron.d file creation + recurring maintenance logs

Supported conclusion

The cron job may have been legitimately installed by the package.

Privileged-group change + scheduled item under that account + later privileged file modification

Supported conclusion

Privilege capability increased before the scheduled action and file change.

Common mistakes

Scheduling mistakes that erase or distort evidence

Deleting the task first

You can lose the exact trigger, action, arguments, account, and history needed for the question.

Treating scheduling as malicious

Updaters, backups, maintenance tools, and administrators all use scheduled execution.

Ignoring the run-as account

Privilege and user context can completely change the meaning of the action.

Reading only the schedule

A trigger means little without the action it launches.

Assuming configured means executed

Use history, logs, process evidence, or output to prove actual execution.

Ignoring package context

A package may legitimately install cron jobs, timers, or scheduled tasks.

Ignoring linked files

Preserve script and executable metadata as part of the evidence chain.

Forgetting your own changes

Disabling or deleting items creates new state and logs that should be documented separately.

Fictional persistence lab

Reconstruct a recurring task from download to execution

11:02Browser

student6 downloads reports.zip into the Windows Downloads directory.

11:04Filesystem

update.ps1 is extracted into C:\Users\student6\AppData\Local\Temp\Reports\.

11:06Task Scheduler

Task ReportUpdater is registered to run every 30 minutes as student6.

11:30Task Scheduler

ReportUpdater starts PowerShell with update.ps1.

11:30Process Evidence

PowerShell launches helper.exe from the same temporary directory.

11:31Network Evidence

helper.exe opens a fictional outbound connection to 203.0.113.120.

Task 01

What establishes the persistence mechanism?

The ReportUpdater scheduled task configured to run every 30 minutes.

Task 02

What links the task to the script?

The task action launches PowerShell with the update.ps1 path.

Task 03

What connects the script to helper.exe?

The observed process parent-child chain at 11:30.

Task 04

Why is the Temp path relevant but not conclusive?

Temporary storage is unusual for recurring execution, but legitimate installers and applications can also use Temp.

Task 05

What proves the task actually executed?

Task Scheduler history plus the observed PowerShell and helper.exe process activity.

Task 06

What should be preserved before disabling the task?

Task configuration/XML, triggers, action, account, run history, script and executable metadata/hashes, process chain, and network evidence.

Lesson checklist

Before moving on

01

I identify the scheduled item's exact name and location.

02

I record the exact trigger or schedule.

03

I record the exact action or command.

04

I record arguments and working directory where available.

05

I record the run-as account or cron owner.

06

I distinguish enabled configuration from actual execution.

07

I check scheduler history or logs.

08

I correlate the item with the process it launches.

09

I preserve linked script or executable metadata and hashes.

10

I check package or application context before labeling it unauthorized.

11

I preserve evidence before disabling or deleting anything.

12

I record my own defensive changes separately.

Reflection

Check your persistence reasoning

Question 1

Why is a scheduled task or cron job not automatically suspicious?

Question 2

What is the difference between trigger evidence and execution evidence?

Question 3

Why does the run-as account matter?

Question 4

How can package logs explain an unexpected cron job or timer?

Question 5

What evidence would you use to prove that a configured task actually ran?

Question 6

Why should the linked script or executable be preserved before removing the scheduler entry?