A Linux server gets cleaned up after an intrusion. The suspicious process is terminated, credentials are rotated, and the system is rebooted during maintenance. Everything seems secure. A few hours later, the same outbound connection appears again.
Situations like that point to persistence. The attacker no longer needs the original exploit because something on the host continues restoring access behind the scenes. Finding that mechanism is often more important than understanding how the compromise started in the first place.
Linux attackers rarely need complicated malware for this. Built-in operating system features already provide reliable ways to execute code, survive reboots, and maintain a foothold. cron sits near the top of that list. It is trusted, widely deployed, and present on almost every Linux distribution. For an attacker, that combination is hard to ignore.
Attackers spend a lot of time looking for ways to keep access after the initial compromise. Getting into a system is one thing. Staying there after a password reset or a reboot is the harder part.
MITRE ATT&CK tracks this behavior under T1053.003: Scheduled Task/Job: Cron, which documents how adversaries use cron jobs for both persistence and execution on Linux systems.
The functionality is already there. It is native to the OS. Because scheduled tasks are expected and necessary, creating a new job requires very little effort. Most defenders spend their time reviewing login events, suspicious processes, or malware alerts. They rarely spend the same amount of time reviewing the configuration files that control scheduled activity.
That environment helps malicious entries blend in. A scheduled downloader or persistence script sits beside legitimate backup jobs, log maintenance scripts, and monitoring tasks. It hides in plain sight, often going unnoticed for months.
Creating cron-based persistence is straightforward. The approach usually depends on the level of access the attacker controls.
When an attacker only controls a standard user account, they often start with their own crontab. They run crontab -e.
From there, they add a task that runs every few minutes. The job might reconnect to command-and-control infrastructure, launch a payload, or download additional tooling. None of it requires elevated privileges.
Root access changes the equation entirely.
A scheduled task running as root inherits whatever control root already has. An attacker who reaches this level can create access that survives reboots while maintaining the ability to execute commands with the highest privileges available on the system.
At that point, the cron job is no longer supporting the intrusion. It becomes part of how the attacker keeps control.
/etc/cron.d/ DirectoryNot every cron entry lives inside a user crontab.
Linux systems use the /etc/cron.d/ directory to store separate scheduling files for applications and services. Attackers like this location because a new configuration file can blend into an already crowded directory. Investigators often review the main crontabs while overlooking a file tucked away in this folder.
That gap is all an attacker needs.
@reboot Directive Sometimes attackers do not care about the recurring execution every hour. They just want their code to run whenever the host comes back online.
The @reboot directive handles this. The configured command launches automatically after startup. Maintenance windows, patch cycles, and power outages become opportunities for the payload to execute again.
The entry may sit quietly for weeks. Then a reboot happens and the payload returns.
Attackers do not always store malware locally on disk.
The cron entry acts as a delivery mechanism. Commands using curl, wget, or python retrieve content from remote infrastructure at regular intervals. Updating the payload becomes as simple as changing a file on the attacker's server.
The cron entry never changes. The payload behind it can.
If you suspect persistence, stop hunting for active processes and start auditing configuration files. You need to see what is scheduled to run.
Start by checking the crontabs for the current user and for root:
crontab -l
sudo crontab -l
Next, inspect the common system-wide locations. A quick way to list these files is:
ls -la /etc/cron.* /etc/crontab /var/spool/cron/
Commands are easy. Interpretation is harder.
Do not just look for files. Look at their contents.
You are trying to identify scheduled commands that do not belong. If you find a file in /etc/cron.d/ that does not match a known application, open it and read the command. If it launches a script, follow the path and see what that script actually does.
A surprising number of investigations stop after locating the cron entry. The useful evidence is usually one step further down the chain.
Finding a cron job is only the beginning. The next step is determining whether the scheduled task is legitimate or suspicious.
When reviewing an entry, ask:
/tmp, /dev/shm, or /var/tmp?base64 strings?The more unusual characteristics a cron job displays, the higher its investigative priority should become.
Large environments require continuous monitoring rather than periodic reviews. Security teams should treat cron configuration files as high-value assets and monitor them the same way they monitor sensitive system binaries.
At that point, the goal shifts from finding cron jobs to monitoring the activity they create. Elastic Security Labs includes cron among the Linux persistence mechanisms defenders should routinely monitor when investigating post-compromise activity.
Use tools such as auditd or File Integrity Monitoring (FIM) to track changes.
You want an alert whenever someone modifies /etc/crontab or creates a new file inside /etc/cron.d/. These locations rarely change on stable systems. Any unexpected modification deserves attention.
A cron entry has to be created somewhere. Catching that change early is often easier than detecting the payload later.
If you have EDR telemetry or system logs, look at parent-child process relationships.
A legitimate maintenance script may launch a shell. What deserves attention is cron consistently spawning network-facing utilities, scripting engines, or unexpected binaries.
Examples include:
cron → curlcron → wgetcron → pythoncron → bashDetection engineers frequently hunt for these execution chains because cron spawning network utilities or scripting interpreters can indicate activity. Elastic maintains a public hunting rule focused specifically on cron-based persistence.
Certain findings consistently move to the top of the queue during a cron investigation. None prove malicious activity on their own, but they appear often enough that they deserve immediate review.
curl, wget, nc, or ssh.base64, or long bash one-liners./tmp/, /dev/shm/, or /var/tmp/.root that do not tie back to a known service or administrative process.Cron remains one of the most reliable persistence mechanisms available on Linux systems because it is simple and effective. Attackers continue using it because they do not need anything more complicated.
Most cron-based persistence is not particularly sophisticated. It works because nobody is looking for it. That makes visibility more valuable than complexity.