Linux · Lesson 12
Cron Jobs & Scheduled Persistence
Review Linux scheduled tasks across user crontabs, system cron files, periodic directories, and anacron while preserving required automation and investigating suspicious persistence.
Scheduled execution is normal on Linux. Backups, updates, cleanup, reporting, and applications often depend on it. The defensive skill is deciding which job is expected, which is misconfigured, and which requires evidence-driven containment.
Lesson Snapshot
Learning objectives
Find scheduled persistence without destroying required automation
Explain how cron, system cron directories, anacron, and user crontabs schedule work on Ubuntu and Linux Mint.
Inspect scheduled tasks without immediately deleting unfamiliar entries.
Distinguish legitimate maintenance jobs from unnecessary, misconfigured, suspicious, or unknown persistence.
Trace a scheduled command to its owner, executable, script, package, environment, logs, and downstream effects.
Preserve evidence before disabling or removing a suspicious scheduled task.
Verify that required maintenance and application jobs still run after changes.
Core idea
A schedule is only the trigger
The real security question is what the task executes, under which account, from which path, with which permissions, and for what required purpose.
Evidence risk
Deleting the scheduler entry can erase the map to persistence
Preserve the entry, referenced scripts, metadata, ownership, logs, and package information before removing a confirmed unauthorized task.
Cron fundamentals
Six concepts behind scheduled execution
cron
cron is a time-based job scheduler. It launches commands according to crontab entries and system scheduling files.
crontab
A crontab contains scheduled entries. Users can have their own crontabs, while system-wide jobs may be defined in /etc/crontab or cron directories.
Owner context
A scheduled task runs under a user identity. User context determines privileges, file access, environment, and impact.
Environment
cron jobs usually run with a smaller environment than an interactive shell. PATH, working directory, variables, and shell behavior can differ.
Persistence
Scheduled execution can be legitimate automation or a persistence mechanism. The schedule itself is not proof of malicious activity.
Verification
A scheduled task is not fully understood until you know what it runs, who owns it, why it exists, and whether required behavior still works after remediation.
Schedule syntax
Understand what the five time fields mean
Minute
0-59The minute of the hour when the job may run.
Hour
0-23The hour of the day when the job may run.
Day of month
1-31Limits execution by calendar day.
Month
1-12Limits execution by month.
Day of week
0-7Limits execution by weekday on many cron implementations, commonly with 0 or 7 representing Sunday.
Command
Executable / shell commandThe actual command cron launches when the time expression matches.
15 2 * * * /usr/local/sbin/backup-jobThis example means run the command at 02:15 each day. On a user crontab there is no separate user field. In /etc/crontab and many files under /etc/cron.d, a user field appears before the command.
Important paths
Scheduled jobs can live in several places
/etc/crontabSystem-wide crontab. Unlike ordinary user crontabs, entries include a user field before the command.
Do not copy user-crontab syntax into /etc/crontab without accounting for the user field.
/etc/cron.d/Package and administrator system cron files.
Entries may be package-managed. Identify ownership before editing or removing.
/etc/cron.hourly/Scripts intended for hourly execution on systems using these directories.
Inspect script contents, ownership, executable permissions, and package origin.
/etc/cron.daily/Scripts commonly used for daily maintenance.
Many legitimate package maintenance jobs live here.
/etc/cron.weekly/Scripts commonly scheduled for weekly maintenance.
Frequency alone does not indicate whether a job is required.
/etc/cron.monthly/Scripts commonly scheduled for monthly maintenance.
Review package ownership and application purpose before changing.
/var/spool/cron/crontabs/Common Ubuntu-family storage location for user crontabs.
Do not edit spool files directly unless you understand the platform behavior; use crontab tools for normal administration.
/etc/anacrontabControls anacron jobs designed to run periodic work even when the machine was powered off at the scheduled time.
Anacron complements cron behavior and can explain jobs that execute after boot.
Inspection first
Inventory schedules before changing them
crontab -lShow the current user's crontab.
sudo crontab -lShow root's crontab.
sudo crontab -u username -lShow a specific user's crontab.
sudo cat /etc/crontabReview the main system-wide crontab.
sudo ls -la /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthlyInventory common system cron locations.
sudo find /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly -maxdepth 1 -type f -lsCollect file ownership, permissions, timestamps, and paths for scheduled scripts.
sudo systemctl status cronReview the cron service state on Ubuntu-family systems.
sudo journalctl -u cron --since todayReview cron service events where journal logging captures them.
sudo grep -i CRON /var/log/syslog | tail -n 50Review recent cron-related syslog entries on systems that log cron activity there.
sudo cat /etc/anacrontabReview anacron schedules and commands.
dpkg -S /path/to/scriptCheck whether a scheduled script belongs to an installed Debian package.
stat /path/to/scriptReview script ownership, permissions, size, and timestamps.
Special schedules
Named schedule shortcuts deserve the same review
@rebootRuns once after the cron daemon starts following boot.
Useful for legitimate startup automation but also valuable for persistence.
@hourlyRuns once per hour.
Frequent schedules deserve review if the command is unfamiliar or resource-heavy.
@dailyRuns once per day.
Common for maintenance and backups; identify purpose before changing.
@weeklyRuns once per week.
Can support maintenance or delayed persistence.
@monthlyRuns once per month.
Long intervals make quick testing more difficult, so validate logic carefully.
Cron environment
Scheduled jobs do not run like your interactive shell
PATH may be limited
A command that works interactively may fail under cron if it depends on a shell PATH that cron does not provide.
Working directory may differ
Relative paths can point somewhere unexpected. Security-sensitive cron jobs should generally use explicit paths.
Shell behavior matters
Cron commonly uses /bin/sh unless otherwise specified. Bash-specific syntax may fail.
Variables may be absent
Interactive profile variables are not guaranteed. Required environment values should be set deliberately.
Output may reveal failures
Cron output can be mailed, logged, redirected, or discarded depending on configuration. Missing visible output does not prove success.
Permissions still apply
The cron daemon does not magically bypass file permissions for non-root users. Execution context matters.
Classification
Required, legitimate, misconfigured, suspicious, or unknown
Required
Evidence
Named by the scenario, supports backups, updates, logs, applications, reporting, or another known required function.
Response
Preserve it and verify the command, permissions, output, and schedule are secure.
Legitimate
Evidence
Package-owned maintenance task or known administrative automation with expected ownership and behavior.
Response
Leave intact unless there is a specific configuration problem.
Misconfigured
Evidence
Required task runs as the wrong user, uses unsafe writable paths, has broken syntax, leaks output, or executes too frequently.
Response
Correct the narrow configuration issue and verify the task still performs its required function.
Suspicious
Evidence
Unexpected root execution, script in /tmp or unusual user directory, encoded command, network download, strange interpreter chain, misleading filename, or persistence after an incident.
Response
Preserve crontab entry, script, metadata, logs, command line, package status, and related files before disabling it.
Unknown
Evidence
Purpose, owner, executable origin, schedule, or application relationship is unclear.
Response
Investigate further instead of deleting it because the name looks unfamiliar.
Persistence indicators
Patterns that increase investigation priority
Unexpected @reboot entry
Boot-triggered execution can maintain persistence. Inspect the command and owner.
Root job launching a user-writable script
A privileged scheduler executing a file writable by lower-privileged users creates a serious trust problem.
Script stored in /tmp or hidden user directory
Location can be suspicious, especially when paired with root execution or network activity.
Encoded or heavily obfuscated command
Obfuscation increases investigation priority because it hides intent.
Repeated download-and-execute pattern
Remote retrieval combined with immediate execution can create persistence or supply-chain risk.
Task recreates a removed file or process
Recurring recreation suggests the scheduler may be the persistence source rather than the visible child process.
Evidence-based reasoning
Investigate the command behind the schedule
A root cron job runs every five minutes
Weak response
Delete it because frequent root jobs are dangerous.
Better reasoning
Inspect the command, executable, package ownership, logs, script permissions, and scenario role. Monitoring or application jobs can legitimately run frequently.
A cron script lives in /tmp
Weak response
Delete the file immediately.
Better reasoning
Treat the location as high-priority evidence. Preserve the job entry, file metadata, script contents, owner, parent directories, and logs before containment.
A daily cron file belongs to a package
Weak response
It must be safe because a package owns it.
Better reasoning
Package ownership increases context but does not prove current configuration is secure. Review the package, script behavior, permissions, and scenario requirements.
A user's crontab is empty
Weak response
There are no cron jobs for that user.
Better reasoning
Also inspect system cron files, /etc/cron.d, periodic directories, root's crontab, and other users.
A job uses curl or wget
Weak response
Any download command is malicious.
Better reasoning
Determine the destination, source, package/application purpose, integrity expectations, and whether the scenario authorizes network retrieval.
A scheduled job is failing
Weak response
Remove it because it does not work.
Better reasoning
Determine whether it is required, inspect logs and environment differences, then repair or remove based on purpose.
Evidence sources
Preserve the persistence chain
User crontab
sudo crontab -u username -lShows the user's scheduled entries at the time of inspection.
System crontab
sudo cat /etc/crontabShows system-wide schedules including execution user.
Cron directories
sudo find /etc/cron.d /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly -maxdepth 1 -type f -lsShows scheduled files with ownership, timestamps, and permissions.
Cron logs
sudo grep -i CRON /var/log/syslog | tail -n 50Can show when commands were launched, depending on logging configuration.
Script metadata
stat /path/to/scriptShows ownership, permissions, timestamps, and other filesystem metadata.
Package ownership
dpkg -S /path/to/scriptShows whether the file belongs to an installed Debian package.
Controlled actions
Preserve before you disable
Edit the current user's crontab
crontab -eUse for intentional administration. Preserve the original entry before removing anything important.
Edit root's crontab
sudo crontab -eRoot jobs have high impact. Review the command and script permissions carefully.
Edit another user's crontab
sudo crontab -u username -eConfirm the user's role and preserve the existing schedule first.
Temporarily preserve but disable one line
# comment the confirmed entry in the appropriate crontab or cron fileCommenting can preserve context better than deleting immediately, but only use a syntax-safe method for the specific file type.
Validate a referenced shell script
bash -n /path/to/scriptChecks Bash syntax only. It does not prove the script is safe or appropriate to execute.
Review executable ownership
stat /path/to/scriptConfirm ownership and permissions before allowing privileged scheduled execution.
High-risk shortcuts
Scheduled-task cleanup that can break the system or erase evidence
Deleting every unfamiliar cron entry
Can break backups, updates, reporting, application maintenance, and other required automation.
Stopping cron entirely
Removes all cron-based scheduling, including legitimate system and application tasks.
Deleting a suspicious script before preserving it
Destroys evidence about commands, network destinations, filenames, and attacker or administrator behavior.
Assuming user crontab review is complete
System cron directories, root, other users, and anacron may still schedule jobs.
Running an unfamiliar cron command manually
Can trigger the exact behavior you are investigating under the wrong context or at the wrong time.
Ignoring script permissions
A root cron job that executes a user-writable script can turn a legitimate schedule into a privilege-escalation path.
Verification
Prove required automation still works
Cron service
Confirm the cron service remains healthy when required.
Required jobs
Confirm backup, maintenance, reporting, or application jobs that the scenario requires still exist.
Removed persistence
Confirm the unauthorized process or file is not recreated by the scheduled task.
Permissions
Confirm privileged jobs reference scripts and directories with appropriate ownership and write permissions.
Logs
Review subsequent cron and application logs for expected execution or unexpected failures.
System function
Verify required applications and maintenance workflows still operate after the scheduling change.
Defensive lab
Investigate fictional cron-based persistence
Read the fictional scenario: nightly backup and daily package-maintenance jobs are required; a root-owned @reboot entry launches /tmp/.sync-agent and requires investigation.
Inventory root, user, system, periodic-directory, and anacron schedules without changing anything.
Preserve the suspicious @reboot line, script contents, stat output, ownership, package lookup, hashes if your lab workflow supports them, and relevant logs.
Trace whether /tmp/.sync-agent launches a process, creates network connections, or recreates other files in the fictional lab.
Classify the required backup and maintenance jobs as Required, and classify the unknown @reboot task as Suspicious only after the evidence supports that conclusion.
Disable the confirmed unauthorized persistence while preserving the original evidence and leaving required schedules intact.
Verify cron health, required jobs, absence of recreation, logs, and normal application behavior.
Lesson checklist
Before moving on
I understand the difference between user crontabs, /etc/crontab, /etc/cron.d, periodic cron directories, and anacron.
I know that system-wide cron entries may include an execution-user field.
I inspect root and multiple user schedules instead of checking only my own crontab.
I trace scheduled commands to their scripts, executables, owners, packages, and logs.
I understand that cron has a different environment from an interactive shell.
I treat unexpected @reboot jobs as high-priority evidence rather than automatic proof of malware.
I preserve suspicious entries and scripts before destructive cleanup.
I review permissions on scripts launched by privileged cron jobs.
I avoid stopping cron or deleting broad sets of jobs during routine hardening.
I verify required scheduled functions after changes.
Reflection
Check your reasoning
Question 1
Why can a command work in a terminal but fail when launched by cron?
Question 2
Why does an @reboot entry deserve careful review?
Question 3
What evidence should be preserved before removing a suspicious scheduled task?
Question 4
Why is a root cron job that launches a user-writable script dangerous?
Question 5
Why is an empty user crontab not proof that no scheduled persistence exists?
Question 6
What should you verify after disabling a suspicious cron task?
Carry this forward
Scheduled persistence is a chain: scheduler, owner, command, script, permissions, logs, and resulting process or network activity. Investigate the whole chain before removing the trigger.