跳转到帖子

背景

很多 Web 入侵事件并不是一开始就能看到明确的 WebShell 或异常进程,更多时候只是访问日志里出现了几个奇怪的请求:异常路径、非常规 User-Agent、短时间高频 404、对历史漏洞路径的批量探测等。对运维和安全人员来说,能不能从这些碎片里快速判断风险级别,往往决定了后续处置是否及时。

这篇文章整理一套我平时做 Web 攻击面排查时比较常用的方法,重点放在 Nginx 访问日志、应用日志和主机侧痕迹的交叉分析。内容偏防守和复盘,不涉及未授权利用,也不会提供攻击载荷,只讨论如何识别、验证和加固。

场景描述

某业务系统上线多年,前端由 Nginx 反向代理,后端是 Java 应用。某天监控发现 404 请求量短时间内升高,同时有少量请求命中了敏感路径规则。业务没有明显异常,但从经验看,这类情况通常有几种可能:

  • 互联网扫描器批量探测常见漏洞路径。
  • 针对特定组件版本的漏洞探测。
  • 业务自身存在历史遗留接口,被外部误扫或撞库式访问。
  • 攻击者已经掌握部分目录结构,正在做进一步枚举。

排查目标不是“证明一定被攻击”,而是回答几个问题:请求从哪里来、访问了什么、是否命中真实组件、是否造成状态变化、是否留下持久化痕迹。

第一步:先把日志切出可分析范围

排查时不要一上来就全量 grep,容易被噪声淹没。建议先按时间窗口、状态码、路径特征做粗筛。假设 Nginx 日志路径为 /var/log/nginx/access.log,可以先看异常状态码分布:

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head

如果已经知道异常时间段,可以按时间过滤。不同环境日志格式不同,下面只是常见格式示例:

grep '10/Mar/2026:14:' /var/log/nginx/access.log | awk '{print $1,$6,$7,$9,$10,$12}' | head -50

再统计访问路径,找出高频异常路径:

grep '10/Mar/2026:14:' /var/log/nginx/access.log 
  | awk '{print $7}' 
  | sort | uniq -c | sort -nr | head -50

如果发现大量类似后台路径、配置文件路径、备份文件后缀、框架默认接口等请求,通常可以先按扫描处理,但仍需要确认是否命中了真实资源。

第二步:识别扫描噪声和有效探测

日志里最常见的是通用扫描噪声,例如访问不存在的管理入口、历史漏洞路径、压缩包和数据库备份文件名等。判断是否值得深入,可以看几个维度:

  • 状态码:大量 404 更偏扫描;200、302、401、403 需要重点看。
  • 响应大小:同一路径不同请求响应大小异常变化,可能说明参数触发了不同逻辑。
  • 请求方法:POST、PUT、PATCH、DELETE 比单纯 GET 更值得关注。
  • 来源 IP:单 IP 慢速访问业务接口,和多 IP 批量扫路径,性质不同。
  • User-Agent:明显工具特征不一定代表高危,但可作为聚类线索。
  • Referer:空 Referer 不一定异常,但与敏感路径组合时要关注。

可以用下面的方式统计某个可疑 IP 的访问行为:

grep '^203.0.113.10 ' /var/log/nginx/access.log 
  | awk '{print $4,$5,$6,$7,$9,$10,$12}' 
  | head -100

也可以按 IP 聚合访问量和状态码,判断是否存在批量探测:

awk '{count[$1" "$9]++} END {for (i in count) print count[i], i}' /var/log/nginx/access.log 
  | sort -nr | head -50

这里建议不要只依赖单条日志下结论。很多真实事件里,最关键的不是“访问了某个敏感路径”,而是“访问敏感路径之后,又访问了一个业务接口,并且状态码从 404 变成了 200”。

第三步:确认是否命中真实组件

如果日志中出现某类组件的典型路径,下一步是确认业务是否真的使用该组件,以及暴露范围是否符合预期。排查思路一般是:

  • 查 Nginx 配置,确认 location 转发关系和静态目录映射。
  • 查应用依赖,确认是否包含相关组件或历史版本。
  • 查路由配置,确认接口是否需要鉴权。
  • 查发布目录,确认是否存在测试文件、备份文件、旧版本包。

查看 Nginx 有效配置时,建议使用:

nginx -T 2>/dev/null | less

重点关注这些配置:

  • root、alias 是否指向了不该暴露的目录。
  • location 匹配顺序是否导致鉴权被绕过。
  • 是否存在临时开放的调试路径。
  • 是否允许上传目录执行脚本。
  • 反向代理是否把内部管理端口暴露到公网。

Java 应用可以从构建文件或部署包确认依赖版本。例如 Maven 项目:

grep -R "artifactId\|version" pom.xml */pom.xml 2>/dev/null | head -100

如果是已经打包的应用,也可以在解压后的 WEB-INF/lib 或容器部署目录中查看 jar 包名称。这里不建议直接在生产环境做破坏性验证,更合适的方式是拉取同版本到隔离环境复现,或通过只读方式确认版本和配置。

第四步:检查是否存在状态变化

很多探测请求本身不会造成影响,真正需要警惕的是后续是否出现了状态变化。可以围绕以下几类痕迹排查:

  • 文件变化:Web 目录、上传目录、临时目录是否新增异常文件。
  • 进程变化:是否出现异常子进程、非常规命令调用。
  • 网络连接:是否有应用进程发起异常外连。
  • 账号变化:是否新增系统账号、应用后台账号、访问令牌。
  • 计划任务:是否出现异常 cron、systemd timer 或启动项。

查看最近变更的 Web 文件:

find /var/www /data/www -type f -mtime -3 -printf '%TY-%Tm-%Td %TH:%TM %p\n' 2>/dev/null | sort

查看上传目录中可疑脚本文件:

find /data/uploads -type f \( -name '*.php' -o -name '*.jsp' -o -name '*.jspx' -o -name '*.asp' -o -name '*.aspx' \) 2>/dev/null

查看应用用户下的异常进程:

ps -eo user,pid,ppid,lstart,cmd --sort=start_time | tail -80

查看当前连接,重点看应用进程是否有不符合业务预期的外连:

ss -antp | head -100

如果发现可疑文件,不建议立即删除。更稳妥的做法是先隔离、备份、记录时间戳和哈希,便于后续溯源和确认影响范围:

sha256sum suspicious_file
stat suspicious_file

第五步:关联应用日志和业务行为

Nginx 日志只能看到入口请求,很多关键细节在应用日志里。例如鉴权失败、参数校验异常、反序列化报错、模板解析错误、SQL 异常、文件上传失败等。排查时可以用访问日志中的时间点、请求 ID、客户端 IP 去应用日志里交叉检索。

如果业务已经接入统一日志,建议按以下字段查询:

  • 请求时间前后 5 到 10 分钟。
  • 客户端 IP 或经过代理后的真实 IP。
  • URI、接口名、控制器方法。
  • 登录用户、租户 ID、角色信息。
  • 异常堆栈和错误码。

一个常见误区是只看 Web 容器 access log,不看业务审计日志。比如某个请求返回 200,可能只是页面正常返回;也可能已经触发了配置修改、文件导入、任务创建等业务动作。对管理后台、文件管理、任务调度、插件市场这类功能,要重点看操作审计。

关键加固建议

排查结束后,应该把发现的问题固化成配置和流程,而不是只封几个 IP。比较实用的加固项包括:

  • 公网只暴露必要路径,管理后台放到 VPN、零信任或内网访问范围内。
  • 关闭默认示例页面、调试接口、历史测试目录。
  • 上传目录禁止脚本执行,静态资源域名与应用执行环境隔离。
  • Nginx 对敏感后缀和隐藏文件增加拒绝规则,如 .git、.svn、备份文件等。
  • 应用依赖建立版本清单,定期比对安全公告。
  • 关键接口增加操作审计,并确保日志包含请求 ID、用户 ID 和来源 IP。
  • 对 404 暴增、敏感路径访问、异常 POST 请求建立告警,而不是只看 5xx。

一个基础的 Nginx 防护配置示例:

location ~ /\. {
    deny all;
}

location ~* \.(bak|old|orig|save|swp|zip|tar|gz|sql)$ {
    deny all;
}

location ^~ /uploads/ {
    types { }
    default_type application/octet-stream;
    add_header X-Content-Type-Options nosniff;
}

注意,这类配置需要结合业务验证,避免误伤正常下载功能。配置变更前建议先在测试环境回放关键路径,或至少通过灰度方式上线。

事件记录模板

做排查时建议保留结构化记录,后续复盘会轻松很多。一个简单模板如下:

项目记录内容
发现时间告警触发时间、人工发现时间
影响资产域名、服务器、应用、容器、版本
异常现象异常路径、状态码、请求量、来源 IP
验证结果是否命中真实组件、是否鉴权、是否状态变化
处置动作临时封禁、配置修复、版本升级、隔离文件
遗留风险待升级组件、待补充日志、待收敛入口

注意点

  • 不要因为来源 IP 是云厂商或海外地址就直接判定为攻击成功,扫描和成功入侵是两回事。
  • 不要只看单个请求,要看请求序列。真实攻击通常会有探测、验证、操作、清理等阶段性特征。
  • 不要在生产环境执行不确定的验证脚本,尤其是会写文件、发请求、触发任务的操作。
  • 发现可疑文件时先留证再处理,避免破坏时间线。
  • 如果涉及用户数据、凭证或后台权限,应按内部应急流程升级,不要只在机器上做局部清理。

总结

Web 攻击面排查的核心不是记住多少漏洞路径,而是建立一套稳定的判断链路:入口日志发现异常,配置和依赖确认暴露面,应用日志验证业务影响,主机侧痕迹确认是否落地,最后再做收敛和加固。

很多事件最后复盘下来,问题不在于没有设备或没有日志,而是日志字段不全、配置长期漂移、旧接口没人维护。把这些基础工作补齐,比临时堆规则更有长期价值。

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

0篇意见

推荐意见

没有意见。

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