漏洞应急排查实战:从异常 Shell 进程到 WebShell 后门清理
PHP2Shell 漏洞应急排查实战:从异常 Shell 进程到 WebShell 后门清理
一、背景介绍
随着 Web 应用不断迭代,PHP 仍然广泛应用于网站、管理后台、API 服务及各类业务系统。由于代码缺陷、组件漏洞或不安全的配置,攻击者可能通过 Web 请求触发远程命令执行,进而获取服务器的执行权限。
当服务器疑似遭受 PHP2Shell 漏洞攻击时,常见现象包括:
- PHP-FPM 派生出异常的
sh、bash等 Shell 进程。 - Web 目录出现未知 PHP 文件或伪装成图片的后门文件。
- 服务器向未知公网 IP 建立异常连接。
/tmp、/var/tmp等目录出现可疑脚本或二进制文件。- 系统计划任务、服务配置或用户账号发生异常变化。
- CPU 占用异常升高,或者网站出现无法解释的访问行为。
需要注意的是,PHP2Shell 并不是一个足以唯一确定漏洞类型的标准名称。实际排查时,应结合具体漏洞编号、受影响组件、PHP 版本及攻击日志进行确认。
本文以 Debian 11 + Nginx + PHP-FPM 环境为例,介绍一套从异常进程发现到事件处置的排查流程。
二、第一步:检查异常 Shell 进程
发生远程命令执行后,攻击者可能利用 Web 服务进程执行系统命令。因此,首先需要检查进程树,确认是否存在异常的父子进程关系。
执行以下命令:
ps -eo pid,ppid,user,lstart,args --forest
重点关注以下类型的进程链:
nginx
└─ php-fpm
└─ sh
└─ curl
或者:
php-fpm
└─ bash
└─ python
上述结构只是示例,并不意味着出现相同结构就一定遭受攻击。某些合法程序也会调用系统命令,需要结合实际业务进行判断。
进一步筛选常见的 Shell 和网络工具:
ps -eo pid,ppid,user,args | grep -E \
'php-fpm|apache2|/bin/(ba)?sh|dash|curl|wget|nc|socat|python|perl' \
| grep -v grep
检查 Web 服务用户的进程:
ps -u www-data -o pid,ppid,lstart,args
检查网络连接:
ss -tpn
如果发现 PHP-FPM 进程启动了不符合业务预期的 Shell,或者相关进程持续连接未知公网地址,应记录 PID、PPID、进程启动时间、运行用户和网络连接信息,作为后续关联分析的依据。
对于仍在运行的可疑进程,还可以检查其实际可执行文件:
readlink -f /proc/<PID>/exe
其中 <PID> 需要替换为实际进程号。
三、第二步:排查 PHP WebShell 后门
异常 Shell 可能只是攻击链中的一个环节。攻击者也可能在服务器上留下 PHP WebShell,以便后续再次进入。
首先检查近期修改的 PHP 文件:
find /var/www -type f \
\( -iname '*.php' -o -iname '*.phtml' -o -iname '*.php5' \) \
-mtime -14 \
-printf '%TY-%Tm-%Td %TH:%TM:%TS %u:%g %p\n' \
2>/dev/null
该命令用于筛选过去 14 天内修改过的相关文件。需要注意,文件时间可能被人为修改,因此不能仅依赖时间戳判断文件是否恶意。
接下来,可以对常见的危险函数进行初步检索:
grep -RInE --include='*.php' \
'eval[[:space:]]*\(|base64_decode[[:space:]]*\(|gzinflate[[:space:]]*\(|shell_exec[[:space:]]*\(|passthru[[:space:]]*\(|proc_open[[:space:]]*\(|popen[[:space:]]*\(' \
/var/www 2>/dev/null
重点检查以下特征:
- 使用动态解码、字符串拼接或多层混淆隐藏代码。
- 通过请求参数控制命令执行或文件读写。
- 在上传目录中发现未经业务允许的 PHP 文件。
- 文件内容与代码仓库、正式发布包或已知版本不一致。
- 文件名看似正常,但实际内容与业务功能无关。
需要强调,base64_decode()、eval() 等函数并非恶意代码的专属特征。扫描结果只能作为线索,最终应通过源代码审查、文件哈希对比、访问日志和进程行为综合判断。
四、第三步:检查临时目录和可疑文件
攻击者可能将脚本、下载文件或其他工具放置在临时目录中。
检查近期新增或修改的文件:
find /tmp /var/tmp /dev/shm -type f -mmin -1440 \
-printf '%TY-%Tm-%Td %TH:%TM:%TS %u:%g %p\n' \
2>/dev/null
上述命令筛选最近 24 小时内发生修改的文件。
对发现的可疑文件,可以先检查类型和哈希:
file /path/to/suspicious_file
sha256sum /path/to/suspicious_file
stat /path/to/suspicious_file
如果需要进一步分析,建议在隔离环境中检查文件内容,不要直接执行可疑脚本或二进制文件。
还应注意,临时目录中存在文件并不必然意味着入侵。正常程序也可能在这些位置创建缓存、临时文件和运行时数据。
五、第四步:排查计划任务和持久化机制
如果攻击者已经获得命令执行能力,可能尝试通过计划任务或系统服务维持访问。
检查当前用户的计划任务:
crontab -l
检查 root 的计划任务:
sudo crontab -l
检查系统级计划任务:
cat /etc/crontab
ls -la /etc/cron.d /etc/cron.hourly /etc/cron.daily
检查 systemd 服务及定时器:
systemctl list-units --type=service --all
systemctl list-timers --all
检查近期登录记录:
last -ai | head -50
分析时应特别关注:
- 未经授权新增的定时任务。
- 指向临时目录或网站上传目录的脚本。
- 使用异常路径启动程序的 systemd 服务。
- 无法解释的账号、登录来源和登录时间。
- 服务配置与变更记录不一致的情况。
发现可疑项目后,应先保存配置、时间信息和相关日志,再判断其是否为恶意持久化机制。
六、第五步:分析 Nginx、Apache 和 PHP-FPM 日志
异常进程可以帮助确定服务器发生了什么,而访问日志有助于还原攻击者如何触发问题。
Nginx 常见访问日志路径:
/var/log/nginx/access.log
Apache 常见访问日志路径:
/var/log/apache2/access.log
可以先检索与可疑请求相关的记录:
grep -Ei 'POST|upload|\.php|cmd=|base64|/tmp/' \
/var/log/nginx/access.log | tail -200
分析时重点关注:
- 异常请求对应的 URL 和 HTTP 方法。
- 请求发生的时间是否与 Shell 进程启动时间吻合。
- 是否存在异常参数、上传请求或不符合业务逻辑的请求。
- 同一来源 IP 是否在短时间内访问多个敏感接口。
- 请求后的响应状态、服务异常和进程变化。
对于 PHP-FPM 和系统日志,可以使用:
journalctl --since "24 hours ago" --no-pager \
| grep -Ei 'php|segfault|error|oom|killed'
如果已经确定攻击发生时间,应进一步缩小日志时间范围,并关联 Nginx、PHP-FPM、系统认证日志和网络连接记录。
需要注意,HTTP 200 不代表请求安全,HTTP 500 也不代表发生了漏洞利用。日志中的可疑字符串同样不能独立证明攻击成功。
七、第六步:如何判断是否已经入侵成功
判断是否成功利用漏洞,不能只依赖某一条命令或单个告警。
建议综合评估以下证据:
| 检查维度 | 重点证据 |
|---|---|
| 进程行为 | PHP-FPM 派生异常 Shell,或启动未知程序 |
| 文件变化 | 新增后门文件,或关键文件与可信版本不一致 |
| 网络行为 | 未经业务授权的外连、异常监听端口 |
| 持久化机制 | 未授权计划任务、systemd 服务或启动项 |
| 认证记录 | 异常登录、账号变化、凭证使用异常 |
| Web 日志 | 可疑请求与进程启动、文件变化时间吻合 |
如果多个维度出现相互印证的证据,特别是发现异常命令执行、未经授权的文件变更和外连行为,就应按照安全事件进行处置,而不是简单地将其视为普通系统异常。
八、第七步:应急处置与恢复
确认服务器遭受攻击后,处置过程应尽量避免破坏现场。
1. 保存证据
记录进程、网络连接、日志和可疑文件的元数据。对于重要事件,应按组织的取证流程保存磁盘镜像或其他证据副本。
2. 限制攻击入口
根据实际情况,通过防火墙、安全组或负载均衡限制异常流量,必要时将受影响主机从生产网络隔离。
如果 Web 服务仍持续执行恶意命令,应优先阻断攻击路径,同时考虑保全易失性证据。
3. 修复漏洞
核实具体漏洞影响的 PHP 版本、扩展或应用组件,并升级到厂商提供的修复版本。不要仅根据“PHP2Shell”这个名称就假设某个特定版本一定受影响。
4. 清理恶意文件与持久化机制
确认文件、任务或服务确属恶意后,按照事件响应流程进行隔离和清理。不要直接批量删除所有命中危险函数的 PHP 文件。
如果系统完整性已经无法确认,优先从可信镜像重新部署,并从干净的备份恢复业务数据。
5. 轮换凭证
如果存在凭证泄露风险,应从可信设备或干净环境中轮换数据库密码、SSH 密钥、API Token 和其他可能受影响的凭证,并检查是否存在复用密码的风险。
6. 复核恢复结果
恢复后继续监控异常进程、网络连接、文件变化和登录记录。确认漏洞已修复、持久化入口已清理,并且系统运行行为恢复正常后,再逐步恢复对外服务。
九、第八步:长期安全加固建议
为了降低同类事件再次发生的概率,可以从以下方面进行加固。
PHP 运行环境
- 持续跟踪 PHP 版本、扩展和应用依赖的安全公告。
- 关闭不需要的扩展和危险功能,但不要将
disable_functions视为完整的安全边界。 - 为 PHP-FPM 配置合理的运行用户、进程池隔离和资源限制。
- 生产环境避免暴露调试接口及详细错误信息。
Web 目录权限
- Web 服务运行用户不应拥有整个项目目录的写权限。
- 上传文件应存储在不可执行的位置,或者独立的对象存储中。
- 对上传文件执行类型、大小和内容校验。
- 将代码部署目录与运行时缓存、日志、上传数据分离。
主机安全
- 采用最小权限原则,限制 Web 服务账号的系统访问权限。
- 监控异常父子进程、未知外连和关键目录变更。
- 定期审计计划任务、systemd 服务和系统账号。
- 保留足够的日志,并将重要日志发送到独立的集中日志系统。
应急能力
- 建立定期备份与恢复演练机制。
- 保留可信的软件包、镜像和代码版本。
- 为高风险服务器制定清晰的隔离、取证、修复和恢复流程。
- 定期开展漏洞验证与安全基线检查。
十、总结
PHP2Shell 类漏洞事件的排查重点,不只是寻找一个可疑 PHP 文件,而是尽可能还原完整的攻击链。
从异常 Shell 进程入手,可以发现潜在的命令执行行为;结合文件系统检查,可以定位可能存在的 WebShell 和恶意载荷;再通过访问日志、网络连接和持久化机制分析,才能进一步判断攻击是否成功,以及攻击者是否留下了后续访问入口。
对于Debian 11 + Nginx + PHP-FPM 环境,建议按照以下顺序开展排查:
异常进程 → 可疑文件 → 临时目录 → 计划任务 → 访问日志 → 漏洞修复 → 恢复验证。
最终目标不是简单地删除几个文件,而是确认攻击入口已被封堵、系统完整性得到恢复,并建立能够及时发现同类攻击的持续监控机制。
安全排查需要结合具体证据。对于尚未确认的异常,应保持审慎判断;对于已经存在多项入侵证据的主机,则应按照正式安全事件进行响应。
- 点赞
- 收藏
- 关注作者
评论(0)