跳转到帖子

背景

这几年在做应急和代码审计时,遇到的 WebShell 事件并不少。真正麻烦的地方往往不是“找到一个可疑文件”这么简单,而是要回答几个更关键的问题:入口在哪里、权限边界是否被突破、是否存在二次落点、代码侧怎么修、日志证据能否支撑结论。

这篇整理的是一套偏实战的复盘思路,适合用于企业内部排查、靶场复现后的总结,或者在代码审计中验证上传、解析、模板、反序列化等风险点。内容只讨论防守视角的分析与加固,不涉及未授权入侵、持久化控制或横向移动操作。

典型场景

某业务系统出现异常外联告警,安全设备提示 Web 目录下存在疑似脚本木马。初步看是上传目录里多了一个扩展名伪装的脚本文件,访问时间与某个后台上传接口请求时间接近。

这类事件中常见的入口包括:

  • 文件上传校验不严,仅检查前端或 Content-Type。
  • 上传目录被 Web 容器当作脚本目录解析。
  • 富文本、附件、头像、导入功能未做统一安全处理。
  • 历史遗留测试接口未鉴权或弱鉴权。
  • 第三方组件存在已知漏洞,攻击者借此写入文件。

复盘时不建议一开始就只盯着木马文件本身,应优先建立时间线,把“请求入口、文件落点、执行行为、外联行为、权限影响”串起来。

日志关联思路

第一步通常是确定可疑文件的文件系统时间。需要注意,mtime、ctime、atime 在不同文件系统和挂载参数下含义不完全相同,也可能被程序写入、复制、解压等行为改变,所以不能单独作为结论。

stat /path/to/webroot/upload/2024/xx/suspicious.php

拿到大致时间后,再从 Web 访问日志中缩小范围。常用字段包括访问时间、请求方法、URI、状态码、响应大小、User-Agent、来源 IP、Referer。

grep '2024:10:18:14:' access.log | grep -E 'upload|file|attach|editor|import'

如果是 Nginx 反代到后端应用,还需要同时看 Nginx access/error log、应用框架日志、PHP-FPM 或 Tomcat 日志。很多时候 Nginx 只看到静态请求,真正的上传处理在后端应用日志里才能确认。

建议按下面几个维度做关联:

维度关注点
入口请求是否存在 POST 上传、导入、编辑器附件请求
落地路径响应体或应用日志中是否出现文件名、相对路径、对象存储 key
执行请求可疑文件落地后是否被访问,状态码和响应大小是否异常
异常参数是否存在长参数、编码参数、非常规 header
外联行为主机侧 DNS、代理、防火墙是否有同时间段连接记录

文件样本的安全分析

对可疑脚本不要直接在生产环境访问。先隔离拷贝,记录哈希,保留原路径和时间信息。

sha256sum suspicious.php
file suspicious.php
strings -a suspicious.php | head -n 50

WebShell 常见特征包括动态函数调用、编码混淆、字符串拼接、异常短小但执行能力很强的脚本、使用 assert/eval 类危险函数、通过变量函数调用系统命令等。这里重点不是复现控制能力,而是判断它是否具备执行任意代码、文件操作、代理转发等风险。

在 PHP 环境中,可以优先检索这些高危调用点:

grep -RInE 'eval|assert|system|exec|shell_exec|passthru|popen|proc_open|base64_decode|gzinflate|str_rot13|create_function' /path/to/webroot

但要注意误报。正常框架、调试工具、缓存文件里也可能出现这些关键字。更可靠的方式是结合文件路径、创建时间、代码风格和调用上下文一起判断。

对于 Java Web 项目,则要关注 JSP/JSPX 文件、可写目录、临时目录、上传目录以及框架生成目录。排查时可以关注非常规 JSP、最近修改文件和包含反射、类加载、Runtime 调用的代码片段。

find /path/to/webapps -type f -mtime -7 \( -name '*.jsp' -o -name '*.jspx' -o -name '*.class' \)

定位入口:从上传链路开始

很多事件最终都落在上传链路。审计上传代码时,不建议只看“是否限制扩展名”,而要看完整处理链路。

  • 鉴权:上传接口是否必须登录,是否校验业务权限。
  • 文件名:是否信任原始文件名,是否可能路径穿越或双扩展名混淆。
  • 类型校验:是否只依赖 Content-Type,是否校验文件魔数。
  • 扩展名策略:是否使用白名单,而不是黑名单。
  • 存储位置:上传目录是否在 Web 可执行路径下。
  • 访问方式:是否通过下载接口读取,而不是直接暴露真实路径。
  • 解析配置:Web 容器是否会把上传目录内文件当脚本执行。

一个更稳妥的处理方式是:上传后重新生成文件名,只保留业务需要的安全扩展;上传目录禁止脚本解析;通过服务端读取文件流返回,避免用户直接访问物理路径。

Nginx 场景下,可以对上传目录增加限制,避免脚本执行:

location /uploads/ {
    autoindex off;
}

location ~* ^/uploads/.*\.(php|php5|phtml|jsp|jspx|asp|aspx)$ {
    return 403;
}

如果是 PHP-FPM,还要确认 fastcgi 的匹配规则没有被错误配置成过宽。历史上不少问题来自类似“任意路径匹配 PHP 解析”的配置。

主机侧排查要点

确认 WebShell 后,需要看它是否被执行过,以及执行后造成了什么影响。主机侧可以从进程、网络连接、计划任务、临时目录、Web 用户权限几个方向检查。

ps aux --forest
ss -tunap
crontab -l
ls -lah /tmp /var/tmp /dev/shm

如果 Web 服务用户是 www-data、nginx、apache、tomcat 等,重点看这些用户是否启动了异常进程、写入了异常文件、访问了不该访问的目录。还要检查应用配置文件是否被读取过,例如数据库配置、对象存储密钥、第三方 API token 等。

有条件的话,可以从 EDR、审计日志或 bash history 辅助判断。但要注意,Web 进程执行命令通常不会留下普通交互式 shell 的历史记录,不能因为 history 干净就排除风险。

代码侧加固建议

修复不能只删除 WebShell。入口不堵住,文件还会再次出现。比较通用的加固措施如下:

  • 上传接口统一走服务端校验,前端校验只能作为体验优化。
  • 使用扩展名白名单,例如图片只允许 jpg、jpeg、png、gif、webp,并结合文件头校验。
  • 上传文件重命名,禁止使用用户传入的原始文件名作为落地文件名。
  • 上传目录放在 Web 根目录之外,必须访问时通过下载接口代理。
  • 上传目录禁用脚本解析和目录浏览。
  • 限制上传大小、频率和并发,记录上传人、来源 IP、文件哈希、落地路径。
  • 对富文本编辑器、导入导出、插件管理等高风险功能做额外审计。
  • 生产环境关闭调试接口、测试路由、临时脚本。

对于 PHP 项目,也可以在 php.ini 层面收紧危险函数,但这不是万能修复,更多是降低风险面:

disable_functions = system,exec,shell_exec,passthru,popen,proc_open

需要注意,有些业务或运维脚本可能依赖这些函数,调整前要在测试环境验证,避免影响正常任务。

证据保全和复盘输出

如果事件需要内部追责或对外说明,建议保留以下信息:

  • 可疑文件原始路径、哈希、大小、时间戳。
  • 相关访问日志原文,不只保留截图。
  • 入口接口、请求时间、来源 IP、账号信息。
  • 执行访问记录和可能的外联记录。
  • 受影响资产范围和权限边界。
  • 已采取的处置动作,包括隔离、删除、修复、上线时间。

复盘报告最好区分“已确认事实”和“推测判断”。例如,日志中确认某 IP 上传了文件,这是事实;该 IP 是否属于真实攻击者,可能还需要代理、跳板、账号盗用等更多证据,不能轻易下结论。

常见误区

  • 只删除木马文件,不修入口。
  • 只看 Web 根目录,不看临时目录、缓存目录、备份目录。
  • 只依赖关键字扫描,忽略变形和业务误报。
  • 忽略对象存储、CDN 回源、反向代理导致的日志断层。
  • 没有记录处置过程,后续无法复盘时间线。
  • 把上传白名单写在前端或网关,后端没有二次校验。

总结

WebShell 事件复盘的核心不是“找到一个文件”,而是把入口、落点、执行、影响和修复闭环串起来。日志关联负责还原时间线,样本分析负责判断能力边界,代码审计负责找到根因,配置加固负责降低再次利用的可能性。

实际处理中,建议形成固定流程:先隔离和保全,再关联日志,然后定位入口,最后修复和验证。这个流程看起来不复杂,但在多应用、多代理、多存储的环境里,很容易因为日志缺失或权限边界不清而出现盲区。平时把上传链路、日志字段、目录权限和应急脚本准备好,真正出事时会省很多时间。

代码审计与漏洞定位示意图
代码审计、调用链与关键函数定位示意

0篇意见

推荐意见

没有意见。

游客
抱歉,你的帖子内容包括我们不允许的字词。请编辑你的帖子,删除下面高亮的屏蔽字。
添加意见…