一、原理 #
cron是一个后台执行的系统服务,每分钟检查一次有没有需要执行的计划任务。如果发现有任务的执行时间到了,cron 就会启动该任务。
crontab(即cron table)定义了所有的cronjob(定时任务),Linux中每个用户都有自己的crontab文件,也有系统级的定时任务(/etc/crontab, /etc/cron.d目录等)。
crontab文件的格式为:
# 任务进程中的环境变量(如果不设置则使用默认值)
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/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; }
#
二、前置条件 #
1、当前拥有的权限 #
(1) 低权限用户的shell √ #
(2) 只有写文件权限 #
CentOS对于crontab文件的格式比较宽松,会自动忽略其中不符合格式的行;其余操作系统如Debian, Ubuntu等对于crontab文件的格式要求严格,如果存在不符合格式的行,则整个文件失效。这个区别是因为它们使用的cron不同(cronie/Vixie Cron)
如果拿到的是指定了格式的写文件(例如redis写数据库文件;写日志文件等),可能对centos有效,但对于其它操作系统无效。
如果是任意文件写,则对任何操作系统都有效。
2、目标主机开启了cronjob服务 #
# 在 Debian/Ubuntu 上
systemctl status cron
# 在 CentOS/RHEL 上
systemctl status crond
# 都能用
ps aux | grep -v grep | grep 'cron'
三、探测cronjob内容 #
要确定目标主机上目前有哪些cronjob,以及对应的文件权限。
1、用户级crontab #
每个用户的crontab在(Debian/Ubuntu)/var/spool/cron/crontabs/[username]或(CentOS/RHEL)/var/spool/cron/[username]中。只有root用户能查看它们。
普通用户能通过crontab -l
查看自己的定时任务,但不能查看其它用户的定时任务。用户级crontab不能指定每个任务由哪个用户执行,所有任务都由自己执行。
普通用户无权直接查看其它用户的crontab,但我们可以通过一些技巧来尝试查看到其它用户(特别是root用户)的crontab执行的命令。例如,通过对普通用户开放的inotify API监视文件系统事件、在/proc 文件系统中扫描进程。
扫描工具:https://github.com/DominicBreuker/pspy
普通用户不一定有权限设置定时任务。如果 /etc/cron.allow 存在,则只有列在这个文件里的用户被允许使用 crontab。如果 /etc/cron.allow 不存在,而 /etc/cron.deny 存在,则列在这个文件里的用户被禁止使用 crontab,其他所有用户都被允许。如果两个文件都不存在,则默认所有用户都被允许设置定时任务。
2、系统级crontab #
系统级crontab一般会开启。包括主系统配置文件/etc/crontab和模块化配置文件目录/etc/cron.d/中的所有文件。所有用户都可以查看这些文件,但只有root用户能修改。和用户级crontab的区别是这里的每条任务必须指定由哪个用户执行。
四、提权方法 #
我们能通过cronjob从写文件权限提升到shell权限,并持久化。如果cronjob配置不当,还能从低权限用户提升到root权限shell。
1、持久化/从文件写权限到shell权限 #
如果有root的文件写权限,可以往 /etc/crontab 中写反弹shell,获得root shell。
如果是低权限的文件写,则只能获得低权限的shell。
持久化方法(渗透测试通用技巧):反弹shell;修改/etc/sudoers文件;写webshell;创建一个SUID Root Shell等。
2、提权 #
crontab提权依赖于不安全的cronjob和cronjob配置。
以下所说的root权限的任务指系统级定时任务或root用户的个人定时任务。
(1)root权限任务执行的脚本可写 #
虽然不能直接修改crontab文件,但可以修改定时任务执行的脚本。修改脚本内容后等待定时任务执行即可。
(2)cronjob路径劫持 #
利用条件:root权限任务满足①PATH环境变量中有当前权限下可写的目录,并且排在比较前面 ②定时任务中存在以相对路径执行的命令
满足这两个条件时,我们在路径变量中可写的目录里放一个同名程序,包含恶意代码。当定时任务查找要执行的相对路径的程序时,按照路径变量从前往后的顺序找,先找到我们写的恶意脚本并执行。
例如:
PATH=/home/user:/usr/bin:/bin
...
* * * * * root test -x /usr/sbin/anacron || (cd / && run-parts --report /etc/cron.daily)
我们把恶意脚本写到/home/user/test中,到时候执行的就是我们写的恶意脚本了。
(3)利用定时任务执行的命令自身的漏洞 #
仔细看root权限的每一条定时任务,如果某条定时任务执行的命令本身存在漏洞,也可以利用。最常见的就是通配符漏洞。
例如某学校的服务器曾经出现的漏洞:
...
* * * * * cd /home/user && tar czf /tmp/backup.tar.gz *
我们在/home/user中:
echo "..." > root.sh:# 创建一个名为 root.sh 的恶意脚本
echo "" > "--checkpoint-action=exec=sh root.sh"
echo "" > "--checkpoint=1"
当*展开后,root.sh被执行。
五、总结 #
本文系统地介绍了Linux的cronjob定时任务和提权方法。在利用cronjob时,有不少细节需要注意,例如不同操作系统对于crontab文件的格式要求、用户级和系统级crontab文件的路径和格式。
另外,本文总结了几种探测cronjob内容的方法和利用不当配置提权的方法。