2019 年,一台 CentOS 服务器上的 Jenkins、Nexus 和 Tomcat,启动后不久就反复消失。最初怀疑 GitLab 占用内存过多,但停掉它后,空闲内存回到约 18 GB,现象仍然存在。
这个变化让我转向其他线索,不过仅凭空闲内存数字,不能排除所有 OOM、容器限制或其他资源问题。真正的转折,是每次故障附近都会出现的一条终端提示。
root 邮箱里反复出现 Cron 邮件
You have new mail in /var/spool/mail/root
查看受保护的系统邮箱后,发现大量相同的 Cron 邮件。主题描述的任务会从外部取得脚本,并直接交给 shell 执行。错误正文包含反复杀进程、修改任务和访问外部服务的痕迹,与正常 Jenkins 或 Nexus 启动逻辑无关。
继续检查可疑脚本,发现它会按进程和资源条件终止程序,并把任务写回多个 cron 位置。这可以解释服务为什么不断被杀,而不只是服务自身启动失败。
这里不提供原下载地址、攻击脚本和可直接执行的载荷。看见“下载后执行”的任务时,不要为了验证而重新访问或运行它。
外联记录不能证明最初入口
当时还观察到本机某个高位端口向外部地址建立连接。它是可疑活动证据,但不能据此说攻击者就是从这个本地端口进入的:高位端口可能只是主动连接的临时源端口。
同样,知道目的端口或地址的归属,也不等于已经证明攻击者身份。最初如何取得权限,需要结合登录、应用漏洞、凭据、服务暴露和时间线判断。
先保全证据,不要边查边删
在获授权、已有响应预案的环境中,可从这些只读方向建立清单:
| 证据 | 要回答的问题 |
|---|---|
| 内核与服务日志 | 是 OOM、服务管理器停止、应用崩溃,还是外部终止 |
| cron 配置与系统邮件 | 谁添加了什么任务,何时运行,是否有多个落点 |
| 进程树与网络连接 | 可疑程序的父子关系、账户、启动时间和外联 |
| 登录、账号与服务配置 | 是否有异常登录、新账号、密钥或启动项 |
| 文件与快照 | 保存内容、时间、哈希及取证来源,避免覆盖证据 |
例如 crontab -l 只列当前账户任务;它不覆盖所有账户、/etc/cron.d、周期任务或其他启动机制。systemd 主机还要看相应服务和 timer,不能把旧 CentOS 的路径当成所有系统的全部持久化位置。
即使命令看似只读,在已被高权限入侵的主机上,其结果也可能被篡改。应按响应流程选择可信工具、记录访问并保全易失性信息,不先重启或大量清理来“试试看”。
当年的临时恢复,不等于完整清除
那次沿已知脚本线索清理后,服务不再反复被杀。但这只是业务现象缓解,不能证明主机已恢复可信;尤其当攻击者已经能改 root 任务时,未知持久化和泄漏凭据仍需处理。
更完整的响应应协调隔离与证据保全,评估受影响范围,从可信环境轮换可能泄漏的凭据,并按情况从干净镜像重建、修补入口和验证恢复。不要在失陷主机上输入新凭据,也不要只删一个已知 URL 对应的文件就结束。CISA 事件响应与恢复手册
这次经历最值得保留的是排查转向:当应用日志解释不了进程消失时,系统自动产生的邮件、任务和跨组件时间线,可能比反复重启服务更接近原因。