计划任务为什么是排查重点
计划任务能让攻击者在拿到权限后长期维持访问,且不需要保持连接,因此是持久化落点里出现频率最高的一类。用户级任务存放在各发行版的 spool 目录中:Debian/Ubuntu 为 /var/spool/cron/crontabs/<用户>,RHEL/CentOS 为 /var/spool/cron/<用户>;系统级任务则在 /etc/crontab、/etc/cron.d/ 与 /etc/cron.{hourly,daily,weekly,monthly} 下。排查要把这几处全看一遍,并注意 systemd timer 是等价的新型落点。
基本信息
| 用户级目录 | /var/spool/cron/crontabs/(Debian 系)、/var/spool/cron/(RHEL 系) |
|---|---|
| 系统级位置 | /etc/crontab、/etc/cron.d/、/etc/cron.{hourly,daily,weekly,monthly}/ |
| 查看命令 | crontab -l -u <用户>(root 可查任意用户) |
| 现代等价物 | systemd timer(systemctl list-timers --all)、at 任务(/var/spool/at) |
| 执行记录 | /var/log/cron(RHEL 系)、/var/log/syslog 或 journald(Debian 系) |
| 文件属性 | Debian 系 spool 目录为 crontabs(复数),文件通常 600 |
典型使用场景
- 排查持久化:找出异常的计划任务及其执行的命令与脚本路径
- 核对已下线业务或离职人员的任务是否仍在运行
- 确认任务实际执行的解释器与工作目录,判断是否在调用外部地址
- 把任务执行时间与日志中的异常行为时间点对齐
- 检查 @reboot 类任务,这类条目在重启后才触发,容易漏查
- 与 systemd timer 交叉排查,避免只查 crontab 而漏掉新式落点
排查清单
排查清单
# 先看 spool 目录结构(注意 Debian 系目录名是 crontabs)
ls -la /var/spool/cron/crontabs/ 2>/dev/null || ls -la /var/spool/cron/
# 逐个用户查看内容
crontab -l -u www-data 2>/dev/null
crontab -l -u root
# 系统级任务全部覆盖
cat /etc/crontab; ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/
# systemd timer 与 at 任务同样要看
systemctl list-timers --all | head -20
ls -la /var/spool/at/ 2>/dev/null
# 执行记录:RHEL 系看 /var/log/cron,Debian 系看 syslog 或 journal
grep -i cron /var/log/syslog | tail -20crontab 行逐段读法
| 字段 | 含义 | 判读要点 |
|---|---|---|
| 分 时 日 月 周 | 执行时间表达式 | @reboot 表示开机触发,容易被漏查 |
| 用户 | 仅系统级任务有此列 | 用户级文件里不带该列,多一列说明是从 /etc/crontab 拷来的 |
| 命令 | 要执行的完整命令 | 关注下载执行、编码串、写向 /tmp 的路径 |
| 重定向 | 输出丢弃或写文件 | 大量 2>&1 >/dev/null 是常见的隐藏痕迹手法 |
| 环境变量行 | PATH、SHELL 等设置 | 被改过的 PATH 会让命令指向攻击者放置的同名文件 |
crontab 内容只用 cat 或 crontab -l 阅读,不要手工执行其中命令。处置前先复制原始文件并记录哈希,因为 crontab 编辑会整体重写文件,原始状态不易保留。
crontab 编辑器保存时会重写整个文件,因此文件 mtime 只反映最后一次编辑时间,不能代表任务最初添加的时间。要判断添加时间,需要结合执行日志与文件系统元数据交叉分析。