首页/安全/应急响应速查/全用户 crontab 排查

全用户 crontab 排查

定时任务是木马存活的主要温床之一:遍历系统里所有用户执行 crontab -l,能看到每条计划任务的时间与命令。

应急响应速查安全更新于 2026-10-13

crontab 与定时任务排查

Linux 的 cron 由 crond 常驻进程驱动,每分钟扫描一次任务表并按时间字段触发命令。任务表分布在三类位置:用户自己的任务存在 /var/spool/cron/<用户>(RHEL 系)或 /var/spool/cron/crontabs/<用户>(Debian 系),系统级任务在 /etc/crontab 与 /etc/cron.d/,另外 /etc/cron.hourly 这类目录由 run-parts 拉起。攻击者偏爱这里,因为一条每分钟执行的任务就足以让被杀的木马在六十秒内复活。

基本信息

单用户查询crontab -l(当前用户);crontab -l -u 用户名 需 root
系统级文件/etc/crontab、/etc/cron.d/*、/etc/cron.hourly|daily|weekly|monthly
用户任务目录/var/spool/cron/<用户>(RHEL);/var/spool/cron/crontabs/<用户>(Debian)
时间字段分 时 日 月 星期,之后是执行用户(仅系统级文件有该列)与命令
特殊简写@reboot、@hourly、@daily、@weekly、@monthly、@yearly
执行记录RHEL 系 /var/log/cron,Debian 系在 /var/log/syslog,部分环境依赖 rsyslog 配置

典型使用场景

  • 木马反复复活时定位是谁在拉起它,确认是否被写成短周期任务
  • 挖矿处置后按清单复查,防止任务表里留着重新下载的脚本
  • 排查 CPU、带宽夜里周期性飙高的告警,判断是否有隐藏任务
  • 做主机基线时留存全量任务表,日后与新版本对比发现变更
  • 交接与上线评审时核对计划任务的归属与执行账号

遍历全部用户的任务

遍历全部用户的任务
for u in $(cut -d: -f1 /etc/passwd); do          # 按 passwd 用户逐个查
  out=$(crontab -l -u "$u" 2>/dev/null); [ -n "$out" ] && { echo "== $u"; echo "$out"; }; done
ls -la /var/spool/cron /var/spool/cron/crontabs 2>/dev/null   # 直接用目录文件交叉核对
cat /etc/crontab; ls -la /etc/cron.d/            # 系统级任务表
ls -la /etc/cron.hourly /etc/cron.daily 2>/dev/null           # run-parts 目录
systemctl list-timers --all | head -n 20         # systemd timer 是另一条时间线,不能忽略

时间字段读法

字段取值范围读法与注意
分0-59*/5 表示每 5 分钟;逗号枚举;连字符表示区间
时0-23使用服务器本地时区,跨时区团队要换算后再判断
日1-31与星期同时限定时各实现行为有差异,攻击者常借此混淆
月1-12部分实现支持英文缩写
星期0-70 与 7 都代表周日
@ 简写@reboot 等@reboot 每次开机执行,是后门最常用的形态

命令列可疑特征

特征典型写法说明
下载即执行curl -fsSL 地址 | sh最常见的一条命令式投毒
编码混淆echo 长串 | base64 -d | sh隐藏真实命令内容,规避关键字检查
掩藏输出命令 > /dev/null 2>&1防止产生邮件与异常日志,正常业务也这么做需结合命令本身判断
落在临时目录/tmp、/dev/shm 下的脚本或二进制重启即失,符合攻击者用完即弃的习惯
短周期*/1 * * * *每分钟执行是保活任务的典型节奏
不要用 crontab -r 清空:它会直接删掉任务表且不留备份,任务内容与文件时间证据一起消失。正确做法是先 cat 出来存档、记录 mtime 与 sha256,再按行删除或整表替换。

留证与清理

留证与清理
mkdir -p /evidence/cron_$(date +%F)
sudo cp -a /var/spool/cron /evidence/cron_$(date +%F)/ 2>/dev/null
sudo sha256sum /var/spool/cron/crontabs/* 2>/dev/null | tee /evidence/cron_hash.txt
sudo grep -RInE 'curl|wget|base64|/dev/shm|/tmp/' /etc/cron.d /etc/crontab /var/spool/cron 2>/dev/null
sudo grep -i cron /var/log/cron 2>/dev/null | tail -n 30   # 查任务真实执行记录
目录法比遍历用户更保险:/var/spool/cron 里可能存在已从 /etc/passwd 删除的账号残留任务文件,按 passwd 遍历会直接漏掉这类条目。

容易漏掉的位置

  • /etc/cron.d 下的独立片段文件:不属于任何用户,删除账号也不影响它生效
  • /etc/crontab 的第六列:系统级任务多一个执行用户列,按用户任务格式读会读错字段
  • /etc/cron.hourly 等目录:脚本文件本身就是任务,不需要时间字段
  • at 队列与 systemd timer:at 是一次性任务,timer 与 cron 互不影响
  • anacron:在笔记本或长期关机的主机上补跑每日任务,容易被当成无任务
  • 容器与宿主机两套 cron:容器内的任务在容器重启后可能消失,宿主机的任务不受影响

扩展核对命令

扩展核对命令
sudo ls -la /etc/cron.d/ /etc/cron.hourly/ /etc/cron.daily/ 2>/dev/null   # 目录型任务
sudo cat /etc/crontab                                                      # 系统级任务表
sudo atq                                                                   # 一次性任务队列
systemctl status crond 2>/dev/null || systemctl status cron 2>/dev/null     # 确认 cron 服务本身是否被停掉
sudo lsattr /var/spool/cron/* 2>/dev/null                                  # 任务文件是否被加不可变属性
排查时顺手确认 cron 服务是运行状态:把 crond 停掉或替换成假服务,也是攻击者让已有任务失效、转而依赖自身守护进程的一种手法,看到任务却从不执行就要往这个方向想。

易错点

  • 只查当前用户的任务:root 之外的服务账号常年也有任务,必须以全量目录 + passwd 双向核对
  • 直接 crontab -r 或删文件:内容与时间戳证据一并丢失,后面无法说明攻击者如何保活
  • 只查 cron 不看 timer:systemd timer 与 cron 是两条独立时间线,只查一条必然漏项
  • 看到 > /dev/null 就判定是恶意:大量正常运维脚本也这么写,要结合命令路径、账号与创建时间综合判断
  • 清理后不复查:任务表可能还有 /etc/cron.d 与 at 队列里的副本,清理完必须按清单全量再过一遍

数据来源与参考

  • crontab(1) 与 crontab(5) 手册

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌