背景
很多 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 攻击面排查的核心不是记住多少漏洞路径,而是建立一套稳定的判断链路:入口日志发现异常,配置和依赖确认暴露面,应用日志验证业务影响,主机侧痕迹确认是否落地,最后再做收敛和加固。
很多事件最后复盘下来,问题不在于没有设备或没有日志,而是日志字段不全、配置长期漂移、旧接口没人维护。把这些基础工作补齐,比临时堆规则更有长期价值。
推荐意见