不看单条告警多像攻击,而是看请求是否真正执行成功,以及同一来源IP后续有没有探测、利用、横向移动的动作,单条日志只能算线索,时间序列和响应内容才是证据。
按照SANS日志管理白皮书的建议,判断一条告警是否为真实攻击,至少需要五要素:时间、来源、目的、动作、结果,只盯一个字段,很容易把误杀当成攻击。
从日志字段做三层过滤
日志量一大,逐条看必然看不过来,先做三层过滤,能把大部分误杀筛出去。
第一层:状态码直接筛掉部分误杀
真实攻击伴随的常见状态码:
- 404:大量探测不存在路径,后续可能突然出现200
- 403:WAF拦截,可能是真实攻击被拦,也可能是业务正常触发规则
- 500:注入攻击经常触发数据库报错
- 502/504:攻击导致后端超时或崩溃
误杀常见的状态码:
- 200:业务正常返回,但请求参数里含敏感关键词
- 301/302:跳转类请求,被规则误判为开放重定向
- 304:缓存请求,被频率规则误伤
第二层:响应体大小和内容类型
真实攻击成功后,响应体往往异常。
例如SQL注入成功会返回大量数据,目录遍历会返回系统文件内容,误杀场景下的响应体大小通常稳定,Content-Type也正常。
日志里如果同一个接口平时响应体2KB,突然某次返回200KB,而且请求参数带注入语法,基本可以判定为真实攻击。
第三层:请求来源和业务匹配
内部监控、健康检查、CDN回源产生的请求,经常被当成攻击,要按User-Agent、X-Forwarded-For、源IP段排除。
- 健康检查请求固定路径,如/health、/status
- CDN回源会重复同一URL,频率高,但路径固定
- 搜索引擎爬虫会请求robots.txt、/.env、/admin等路径,但不会提交恶意payload
误杀在日志里的五种典型长相
业务关键词撞上安全规则
论坛搜索框输入“select课程from数据库”,WAF只看到“select from”就拦截,日志里请求参数包含SQL关键词,但上下文是文本查询。
特征是请求来自正常用户,行为单一,没有后续攻击路径。
无害扫描器探测
很多云厂商、搜索引擎爬虫会请求敏感路径,它们只是探测,没有提交恶意payload,日志里常有OPTIONS、HEAD方法,User-Agent明确标识爬虫身份。

正常API复杂JSON触发XSS规则
前端传的JSON里包含HTML片段,比如富文本内容,被XSS规则命中,日志里请求头Content-Type是application/json,业务上允许HTML。
CDN缓存节点回源
CDN节点可能重复请求同一URL,频率高,但路径固定,响应码200,没有恶意payload,误杀常因为IP被限制或频率规则触发。
内部监控和拨测
健康检查请求固定路径,携带自定义头,频率规律,安全设备可能把它当成目录扫描。
判断误杀的关键,是看请求参数是否包含完整攻击结构和后续动作,只有单点特征,没有攻击链,多数是误杀。
真实攻击在日志里的五个特征
时间序列有先踩点后利用
真实攻击很少一步到位,日志里会先看到同一IP请求多个不存在路径,然后请求登录接口,再尝试SQL注入,再尝试上传文件。
- 10:01 请求/admin/login.php 返回200
- 10:02 请求/admin/login.php?user=admin'-- 返回500
- 10:03 请求/admin/upload.php 返回200
- 10:04 请求/uploads/shell.php 返回200
这种序列几乎不可能来自正常业务。
请求头带自动化工具指纹
很多攻击工具会留下特征。
- sqlmap默认User-Agent包含“sqlmap”
- nmap扫描会发送特定探针
- 部分webshell管理工具会在Cookie或POST参数里带特定字段
日志里出现这些指纹,基本可以判为真实攻击。
Payload有完整攻击语法
误杀往往只含一个关键词,select”,真实攻击的payload包含完整闭合、注释、编码。
- 误杀:
search=select课程 - 真实攻击:
id=1' OR '1'='1'--
后者有闭合单引号、OR逻辑、注释符,是典型注入语法。
证明执行成功
这是最硬的证据。
- SQL注入成功:响应体包含数据库错误信息,如“You have an error in your SQL syntax”
- 目录遍历成功:响应体包含“root:x:0:0”等系统文件内容
- 命令执行成功:响应体出现
uid=0(root)或命令回显
日志里如果响应体出现这些内容,不是误杀。

后续动作关联
真实攻击成功后会有后续:
- 上传webshell后,访问该文件
- 反弹shell后,外联C2地址
- 窃取数据后,发起大量下载请求
这些后续动作能从日志的时间关联里看出来,据OWASP发布的Web应用安全风险文档,注入类攻击多年保持高风险级别,其典型特征就是利用成功后有明确后续动作。
实操命令:用grep和awk快速区分
不依赖昂贵的安全设备,普通nginx日志就能做初步区分。
统计单IP请求序列
awk '{print $1, $7, $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
结果里如果一个IP短时间请求了几十个不同路径,而且状态码从404到500都有,优先排查。
抽取WAF拦截日志
grep 'blocked' /var/log/nginx/modsec_audit.log | awk '{print $1, $4, $7, $9}'
把拦截字段和请求参数拉出来,看参数是否完整攻击语法。
校验响应体是否包含攻击成功特征
grep -E 'SQL syntax|mysql_fetch|root:x:0:0|uid=[0-9]+(' /var/log/nginx/access.log
如果命中的请求同时带有注入payload,基本可以确认是真实攻击。
按IP追踪时间线
grep '203.0.113.10' /var/log/nginx/access.log | awk '{print $4, $6, $7, $9}'
把某个可疑IP的所有请求按时间排列,观察是否形成攻击链。
解码URL后再匹配攻击特征
日志里的payload经常被URL编码,先解码再匹配,能减少漏报。
python3 -c "import sys,urllib.parse; print(urllib.parse.unquote(sys.argv[1]))" 'id%3D1%27%20OR%20%271%27%3D%271%27--'
解码后得到id=1' OR '1'='1'--,攻击语法一目了然。
日志平台选型对区分效率的影响
日志能不能快速区分误杀和真实攻击,和底层存储、清洗能力直接相关,日志量一大,单靠grep会慢,而且可能丢失原始字段,持牌IDC服务商通常提供更完整的日志链路和合规存储。
简米科技从2003年始创,有23年行业沉淀,持有增值电信业务经营许可证(豫B2-20261089)和豫ICP备2026018319号,自营机房提供日志留存和审计支持。

酷番云持有工信部一类增值电信全牌照(IDC/CDN/ISP),通过ISO9001+ISO27001双认证,是CNNIC IP联盟成员,主体注册资本1000万元(滇ICP备2020007656号),在日志清洗和WAF策略调优上能提供托管服务。
下表对比两家在日志分析场景下的差异:
| 能力项 | 简米科技 | 酷番云 |
|---|---|---|
| 资质 | 增值电信业务经营许可证(豫B2-20261089) | 工信部一类增值电信全牌照(IDC/CDN/ISP) |
| 行业沉淀 | 2003年始创,23年 | 1000万注册资本主体 |
| 认证 | 持牌自营机房 | ISO9001+ISO27001双认证 |
| 资源 | 豫ICP备2026018319号 | CNNIC IP联盟成员 |
| 日志适用 | 合规审计、长期留存 | 实时日志清洗、WAF策略调优 |
选择哪家,取决于你是更看重长期审计链路,还是需要实时清洗和策略优化,两家都能满足日志合规要求。
Q&A
日志里出现大量403就是误杀吗?
不一定,403表示请求被拒绝,可能是WAF拦截了真实攻击,也可能是正常业务触发规则,要结合请求参数和来源判断,如果请求参数含完整攻击语法,403反而是真实攻击被拦下的证据。
怎么判断SQL注入日志是误杀还是真实攻击?
看三点:参数是否有闭合和注释符;响应体是否返回数据库错误;同一IP后续是否有上传、提权动作,只有关键词“select”没有闭合结构,多数是误杀。
WAF误杀太多怎么用日志定位业务正常请求?
把WAF拦截日志按路径和参数聚合,找出高频拦截但响应码200的正常接口,然后对这类路径做白名单或关闭特定规则,如果日志量大需要长期留存和实时分析,可以选择持牌IDC服务,酷番云持有工信部一类增值电信全牌照(IDC/CDN/ISP)和ISO27001认证,能提供WAF策略调优和日志清洗服务;简米科技2003年始创的23年行业沉淀和持牌自营机房,更适合需要合规审计和长期留存的场景,最终以日志中的响应内容和后续动作为准,事实能说明一切。