作者:Mavis · 实战复盘 · 2026-06-29
适用读者:运维、安全工程师、WAF 策略调优人员
数据来源:3 份百度云 WAF 真实访问日志(共 72,239 条请求,跨 2 小时)
阅读时长:约 15 分钟
写在前面:这不是一份教科书
这是一份实战复盘。整个下午我都在和 3 份百度云 WAF 日志较劲,看着一波又一波攻击者来来回回,有些被拦了,有些没拦住,有些换了个 IP 接着来。
最大的感受:WAF 是个”防君子不防小人”的工具——它能拦住脚本小子,但面对有组织的爬虫攻击者,默认配置远远不够。WAF 策略不是一次配好就完事,而是要跟着攻击者持续迭代。
这篇文章会讲到:
- 我从 3 份日志里怎么发现攻击者的
- 哪些攻击 WAF 没拦住,为什么没拦住
- 怎么一步步加规则,把漏放的攻击者关到门外
- 业务侧应该怎么配合,因为光靠 WAF 远远不够
数据全部真实(从脱敏后的 WAF 日志里抽),规则全部可落地(百度云 WAF 控制台可直接配置)。
一、背景:7 万次请求,2 小时,谁在打我的网站
数据来源:
- 日志 1:11:13:28 – 11:20:xx,10,837 条,7 分钟
- 日志 2:11:49:45 – 12:04:43,23,546 条,15 分钟
- 日志 3:13:53:37 – 14:23:36,37,856 条,30 分钟
- 合计:72,239 条请求
3 份日志跨 2 小时,期间攻击者没有停过。
1.1 三份日志的状态码分布对比
| 状态码 | 日志 1 | 日志 2 | 日志 3 | 含义 |
|---|---|---|---|---|
| 200 | 6,655 (61%) | 11,143 (47%) | 18,767 (50%) | 放行 |
| 502 | 1,847 (17%) | 5,962 (25%) | 9,988 (26%) | 上游故障(不是 WAF 拦的) |
| 304 | 980 (9%) | 2,939 (12%) | 2,302 (6%) | 缓存命中 |
| 403 | 867 (8%) | 1,704 (7%) | 4,401 (12%) | WAF 拦截 |
| 206 | 293 (3%) | 678 (3%) | 1,123 (3%) | 范围请求 |
| 444 | 4 (0.04%) | 359 (1.5%) | 77 (0.2%) | Nginx 静默关闭(CC 防护) |
| 499 | 22 | 185 | 72 | 客户端提前关闭 |
| 其他 | 169 | 576 | 1,126 | 301/302/404/500/504 |
关键观察:
- WAF 拦截率只有 8%~12%——剩下近 9 成请求被放行
- 502 一直占 17%~26%——上游源站(47.97.159.125)在持续故障,这个不是 WAF 的事,但说明业务侧在崩溃边缘
- 444 状态码(CC 防护 drop)是真正能完全阻断攻击的,但触发条件很严,只有极少量请求达到
1.2 WAF 拦截的三个模块
WAF 拦截请求里,final_action 字段告诉你它是怎么拦的:
| 模块 | 规则 ID | 日志 1 | 日志 2 | 日志 3 | 触发逻辑 |
|---|---|---|---|---|---|
blacklist | 1000101496 | 742 (85%) | 1,485 (72%) | 3,894 (87%) | IP 黑名单 |
custom | 1000101002 | 125 (14%) | 217 (10%) | 501 (11%) | 自定义 URL/规则 |
auto_cc | 1000101459 | 4 (0.5%) | 359 (17%) | 77 (2%) | CC 频次防护 |
waf (规则 3102) | 3102 | 0 | 0 | 1 (0.02%) | 内置 WAF 规则(只出现过 1 次) |
关键洞察:
- blacklist 占 70~85%——WAF 主要靠”按 IP 拉黑”在拦
- auto_cc 在日志 2 暴增到 17%——那次有攻击者触发了频次
- waf 规则 3102 三份日志只触发 1 次——内置 WAF 规则几乎没起作用,基本靠人工维护的黑名单
二、从日志里识别攻击者:我的分析方法
我用的方法可以总结成 5 步,任何安全分析都可以套这个流程。
步骤 1:先看 final_action 字段(WAF 标记)
不是所有”非 200″都是 WAF 拦的。403/444 不一定是被拦,可能是源站拒绝。
金标准是 final_action / final_module / final_rule_id 三个字段:
- 有
final_action=block= WAF 拦了 - 没有
final_action但状态 403/444 = 源站或 Nginx 自己拒绝
步骤 2:看 WAF 拦了哪些 IP、什么路径
from collections import Counter
import json
with open('waf.log') as f:
records = [json.loads(l) for l in f]
# 提取被 WAF 拦的请求
blocked = [r for r in records if r.get('final_action') == 'block']
# 按 IP 看谁被打得最凶
ip_c = Counter(r['client_ip'] for r in blocked)
print(ip_c.most_common(10))
# 按路径看被拦最多的是什么
uri_c = Counter(r['uri'] for r in blocked)
print(uri_c.most_common(10))
日志 1 输出:
[('42.187.135.241', 85), ('42.187.132.81', 76), ('42.187.135.31', 56),
('42.187.138.247', 52), ('220.181.51.118', 26), ...]
# 路径:
# /file/upload/202304/24/7437071.jpg 多次
# /file/upload/202304/24/7037071.jpg 多次
一眼看出:一群 IP 在刷 /file/upload/yyyyMM/dd/数字ID.jpg——典型的文件 ID 暴力枚举。
步骤 3:看漏放的请求(200 但行为异常)
WAF 拦的是冰山一角,漏放的才是真正的问题。我用的几个漏放检测规则:
# 规则 1:空 UA + 200(自动化脚本特征)
empty_ua_200 = [r for r in records
if (not r.get('user_agent')) and r['status'] == 200]
# 规则 2:老版本 UA + 200(2014 年 Firefox,真实用户不会用)
old_ua = [r for r in records
if r['status'] == 200 and 'Firefox/3[0-9]' in r.get('user_agent','')]
# 规则 3:1 秒内 5+ 次请求(并发,人类不可能)
from collections import defaultdict
ip_times = defaultdict(list)
for r in records:
if r['status'] == 200:
ip_times[r['client_ip']].append(r['start_time']//1000)
# 然后扫描每个 IP 的时间序列
# 规则 4:URL 枚举模式
import re
enum = [r for r in records
if r['status'] == 200 and re.match(
r'/(news|file/.*)-\d+\.(html|jpg|png)$', r['uri'])]
步骤 4:看 JA3/JA4 指纹(TLS 层指纹)
JA3 是 TLS ClientHello 的哈希,JA4 是改进版(把顺序归一化)。真实浏览器 = 1 个 JA3,反指纹爬虫 = 几十到几百个 JA3。
from collections import Counter
ja3_c = Counter(r.get('ja3_hash') for r in records if r.get('ja3_hash'))
# 看 top 5 ja3 的样本 UA,识别"JA3 数量多 = 反指纹"
步骤 5:画像 + 落规则
识别出攻击者后,用 IP 段、UA、JA3 指纹、行为模式四个维度建规则。
三、5 大攻击者群画像
3 份日志里,我识别出 5 类有组织、有规模的攻击者群。每一个都值得专门处置。
3.1 攻击者群 A:42.187.x 段(天津 IDC)— 文件 ID 暴力枚举
画像:
- 跨 3 份日志,被 WAF 累计拦截 6,121 次
- 8~20 个 IP 持续活跃,IP 段在
42.187.132.0/24/42.187.135.0/24/42.187.138.0/24 - 全部 UA:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120 - 目标路径:
/file/upload/yyyyMM/dd/数字ID.jpg
他们在做什么:
14:21:15 42.187.135.241 GET /file/upload/202304/24/7437071.jpg → 403
14:21:15 42.187.135.241 GET /file/upload/202304/24/7037071.jpg → 403
14:21:15 42.187.135.241 GET /file/upload/202304/24/7337071.jpg → 403
14:21:16 42.187.132.81 GET /file/upload/202404/01/7138520.jpg → 403
...
这是典型的”上传文件 ID 暴力破解”——攻击者通过连续数字 ID 遍历,试图下载别人上传的私有文件(头像、合同、票据、身份证等)。这是数据泄露风险,不是带宽消耗。
WAF 拦截效果:✅ 拦了(blacklist 规则 1000101496)
建议处置:
- 整段封禁:
42.187.132.0/24/42.187.135.0/24/42.187.138.0/24 - 业务侧加
/file/upload/鉴权(限同登录用户/限时间) - ID 改成 UUID,杜绝数字 ID 枚举
3.2 攻击者群 B:220.181.51.x 段(百度云 IDC)— 假百度爬虫
画像:
- 累计拦截 1,150+ 次
- 8 个 IP 持续活跃:
.85 / .88 / .90 / .92 / .113 / .116 / .118 / .120 - UA 写的是 Chrome/48(2016 年版本),但 JA3 是真实百度爬虫的
- 目标路径:同样是
/file/upload/数字ID.jpg
判断:
- 220.181.51.x 是百度云/BCC 主机段
- JA3
0149f47eabf9a20d0893e2a44e5a6323是真实百度爬虫的指纹 - 但 UA 写 Chrome/48 是伪装——真实百度爬虫会用现代 Chrome UA
所以这帮人是:借百度云主机,用真实百度爬虫的 TLS 指纹,但伪装浏览器 UA,绕过 JA3 黑名单。有组织、有预谋。
WAF 拦截效果:✅ 拦了 100%(整段已经触发 IP 黑名单)
建议处置:
- 整段封禁
220.181.51.0/24 - 关键:不影响真实百度爬虫(它们在 180.76.15.x / 220.181.108.x 等段)
- 百度站长平台申诉下,封禁这个假冒段
3.3 攻击者群 C:112.82.218.0/24 段(江苏 IDC)— 反指纹全站抓取 ⚠️
这是 3 份日志里我花最多时间分析的攻击者——因为他们最狡猾。
第一次出现(日志 1,11:16:51-11:18:24)
单 IP 112.82.218.254:
- 92 秒内 2,913 次请求
- 1 秒最高 68 次
- 流量 48.17 MB(占总流量 38%)
- UA:
Chrome/124.0.0.0 Safari/537.36 (Mac OS X 10_15_7) - 目标:
zhanhui.aifu360.com全站静态资源 - WAF 拦截:0
第二次出现(日志 2,12:02:13-12:04:07)
单 IP 112.82.218.134:
- 113 秒内 1,729 次请求
- 1 秒最高 60+ 次
- 完全相同的行为模式
第三次出现(日志 3)
4 个新 IP,各 7~8 次:
.173 / .238 / .244 / .250- 明显是”探活”——只发少量请求,试探这些 IP 是否被封
工具特征”DNA 指纹”
我把两次大规模攻击的所有维度都拉出来对比,发现这个工具的”DNA”是这样的:
| 维度 | 特征 | 为什么是”恶意” |
|---|---|---|
| UA | Chrome/124 在 Mac 和 Linux 间切换 | 真实浏览器不会这样切换 |
| JA3 数量 | 71~85 个(每次连接随机) | 真实 Chrome 只有 1 个 |
| JA4 | 99% 都是 t13d1516h2_8daaf6152771_d8a2da3f94cd | JA4 把同行为归一,说明 TLS 库固定,只是顺序打乱 |
| TLS 协议 | 100% TLSv1.3 | 真实用户有 TLS 1.2 的,100% 一致是工具特征 |
| accept-language | 永远 en-US,en;q=0.9 | 中国大陆 Chrome 99% 是中文 |
| sec-ch-ua | 写 "Chromium";v="147"(不是 "Google Chrome";v="124") | UA 在撒谎——版本和 User-Agent 不一致 |
| sec-ch-ua-platform | 固定 "Linux" | 但 UA 切换 Mac/Linux,平台标记固定 |
| 抓取顺序 | 先 19 次 502 探测入口页,再 200 抓资源 | 标准爬虫 BFS 行为 |
| 每个资源大小 | 100% 固定(如 jquery.js 永远 85,755 bytes) | 资源没变化,工具反复拉 |
| 访问次数 | 每个资源访问 95~98 次 | 真实浏览器是 HTTP/2 多路复用,不会重复拉 |
| 时间间隔 | 中位数 13ms,平均 111ms | 真实用户至少 100ms+,13ms 是并发打 |
| 源端口 | 229 个不同端口(33,758~59,368) | 真实浏览器复用连接,1~3 个端口 |
| Referer | 3,301 次硬编码 zhanhui.aifu360.com/ | 真实用户会随页面跳转变 |
WAF 拦截效果:❌ 完全漏放(因为没频次限速,JA3 随机化绕过了指纹)
WAF 默认配置拦不住的原因:
- 按 IP 封禁:它每次换 IP 就过了
- JA3 黑名单:它每次连接都换 JA3,黑名单失效
- JA4 黑名单:和正常 Chrome 用户一样,没法区分
- UA 黑名单:Chrome/124 看起来正常
- 没有频次限速:1 秒 60+ 次不限流
我加的规则(后面会讲):基于 accept-language=en-US + sec-ch-ua 写 Chromium 147 这两个”撒谎”特征,直接封。
这个工具在做什么
全站镜像/SEO 采集。它在抓 zhanhui.aifu360.com 的模板和静态资源,而不是数据/内容。意图大概率是仿站或 SEO 站群。
3.4 攻击者群 D:Firefox/32 老 UA 群 — 业务接口撞库 ⚠️
画像:
- 累计 1,496+ 次
- 全部 UA 是 Firefox/32.0(2014 年发布,真实用户不会用)
- TOP 8 个 IP:
223.72.43.43/120.7.16.33/112.21.2.68/114.227.173.48/116.235.8.202/111.31.251.151/120.7.17.84/39.166.43.2/14.153.12.28/183.241.164.165 - 目标:
/member/aifu360f_b.php(会员中心业务接口)
WAF 拦截效果:❌ 完全漏放
具体行为:
- 全部访问
/member/aifu360f_b.php - 50% 是
?mid=5,50% 无参数 - 49 次 Referer 用 HTTP(其他都是 HTTPS)——HTTP/HTTPS 混用,工具特征
- 同一 IP 短时间 200+ 次,1 分钟最高 22 次
这是撞库/越权测试。30 分钟内攻击量从 200 涨到 376,说明在升级攻击。
我加的规则:UA 包含 Firefox/3[0-9] 直接 403(后面讲)。
3.5 攻击者群 E:Chrome/69 Mac 假浏览器 — 测登录接口
画像(日志 3 新出现):
- 545 次,分散在 30+ 个 IP,每个只 2~6 次
- UA:
Macintosh; Intel Mac OS X 10_13_5 ... Chrome/69.0.3497.100(2018 年版本) - 目标:
/login.php(21 次)+/index.php(8 次)+ 静态资源
WAF 拦截效果:❌ 完全漏放
判断:
- 30+ 不同 IP,每个只 2~6 次 = 分布式撞库(避免触发单 IP 频次)
- 同时拉静态资源(模拟”先看登录页 → 加载依赖”的真实流程)
- 这是有组织、有预谋的撞库行动
我加的规则:/login.php + Chrome/69 + OS X 10_13 组合规则(后面讲)。
3.6 攻击者群 F:头条 Bytespider 跨云爬虫 — 反爬侦察
画像(日志 3 新出现):
- 297 次
- IP 全部是 GCP(Google Cloud):
34.92.x/35.220.x/34.96.x/35.241.x - UA 写
Bytespider(头条爬虫) - 目标:
/file/script/page.js这个资源被访问 122 次(41%)
关键观察:
- 头条爬虫专门抓 page.js
- page.js 里有反爬虫检测代码(JS 挑战、滑块验证等)
- 头条在”反反爬”——抓你的反爬代码做反编译,准备绕过
WAF 拦截效果:❌ 完全漏放(因为 UA 是合法爬虫名)
我加的规则:基于”单 IP 短时间内抓特定 JS 文件”的行为模式(后面讲)。
四、WAF 没拦住的根本原因分析
3 份日志,72,239 请求,只拦了 9,110(12.6%)。为什么漏放这么严重?
4.1 默认配置是”按 IP 拉黑”,不是”按行为检测”
百度云 WAF 默认只拉黑已经触发过 WAF 规则的 IP。新 IP 第一次来,只要请求本身没匹配到规则,就放行。
所以 112.82.218 段换了 4 次 IP,每次都是”新 IP”,WAF 都没拦住。
4.2 没有频次限速
WAF 的频次防护(auto_cc)需要单独配置。默认配置下,1 秒 60+ 次和 1 秒 1 次是一样的——都放行。
4.3 UA 黑名单要手写
WAF 没内置”老版本 Chrome 老版本 Firefox 都是攻击者”的规则。要靠人工配。
4.4 业务接口不在 WAF 防护范围
/member/* /login.php /api/* 这些路径是业务路径,WAF 不知道哪个是正常请求、哪个是攻击。
比如 /member/aifu360f_b.php?mid=5——这是正常的会员中心操作还是业务接口撞库?WAF 看不出来,只能靠行为特征(频次、UA、Referer 异常)。
4.5 反指纹工具,JA3 黑名单失效
112.82.218 段每次连接换 JA3,JA3 黑名单只对”单指纹”有效,被这种工具完全绕过。
五、WAF 规则配置过程:从 0 到 1
下面是我根据这 3 份日志实际配置的规则,每一条都有数据依据。
规则 1:IP 段黑名单(最有效)
# 百度云 WAF 控制台 → 防护策略 → 黑名单 → IP 黑名单
# 直接批量粘贴
# 天津 IDC 段
42.187.132.0/24
42.187.135.0/24
42.187.138.0/24
# 百度云假爬虫段
220.181.51.0/24
# 同一伙人换 IP 段
112.82.218.0/24
# Firefox/32 攻击者群(60+ IP,完整清单见附录)
223.72.43.43
120.7.16.33
112.21.2.68
114.227.173.48
# ... 完整清单见文末
效果预期:这一条规则能直接干掉 70~80% 的攻击量。
规则 2:UA 黑名单(对抗老版本 UA 群)
# 百度云 WAF 控制台 → 防护策略 → 访问控制 → UA 黑名单
# 支持正则匹配
# 老版本 Firefox(2014 年,真实用户不会用)
^.*Firefox/3[0-9]\..*$
# 假浏览器 UA(2016-2018 年的 Chrome 版本,主要用于伪装)
^.*Chrome/(4[5-9]|5[0-9]|6[0-9]|7[0-9])\..*$
# 注:这一条要小心,可能误伤少量真实用户。生产环境建议先观察 1 周,加白名单
# Windows XP / Vista(早淘汰的 OS)
^.*Windows NT 5\..*$
^.*Windows NT 6\.0.*$
# 老 Android(4-6)
^.*Android [1-6]\..*$
# 工具型 UA(几乎 100% 自动化)
^.*python-requests.*$
^.*curl/.*$
^.*wget/.*$
^.*scrapy.*$
^.*Go-http-client.*$
^.*okhttp.*$
效果预期:
- Firefox/32 群攻击(1,496 次)直接 0
- Chrome/69 假浏览器群(545 次)直接 0
- python-requests/curl 等脚本请求(共 8 次)直接 0
规则 3:频次限速(对抗高频请求)
# 百度云 WAF 控制台 → 防护策略 → CC 防护
# 建议配置(以单 IP 为单位)
通用规则:
- 60 秒内超过 30 次 → 触发滑块
- 60 秒内超过 60 次 → 直接 403
- 5 秒内超过 10 次 → 触发滑块
# 对静态资源路径(更严)
/file/script/, /skin/, /lang/ 路径:
- 60 秒内超过 20 次 → 403
效果预期:
- 112.82.218 段换 IP 也会被频次卡住(因为每个新 IP 第一次来也是高频)
- 各种高频 IP 都会被压制
规则 4:业务接口专项防护
# /login.php 撞库防护
location = /login.php {
# 业务侧:加图形验证码
# WAF 侧:UA 黑名单(规则 2)+ 频次限速(规则 3,1 分钟 >5 次触发)
# 单独规则:老 Mac OS X 10_13 + Chrome/69 的组合
if ($http_user_agent ~* "OS X 10_13" && $http_user_agent ~* "Chrome/69") {
return 403;
}
}
# /member/ 业务接口
location ~* ^/member/ {
# 1 分钟超过 5 次 → 滑块
# 1 分钟超过 10 次 → 403
# Firefox/32 已经在规则 2 里全拦,这里是兜底
# 加 referer 校验:必须从 www.aifu360.com 主页进入
valid_referers aifu360.com *.aifu360.com;
if ($invalid_referer) { return 403; }
}
# /admin/ 后台(高危)
location /admin/ {
# IP 白名单(只允许运维和办公室 IP)
allow 1.2.3.4; # 办公室出口
allow 10.0.0.0/8; # 内网
deny all;
}
规则 5:反指纹检测(对抗 112.82.218 段)
最关键的规则——基于”撒谎的 UA 特征”识别这个工具:
# 规则 5.1:accept-language 是英文(中国大陆用户 99% 是中文开头)
if ($http_accept_language = "en-US,en;q=0.9") {
return 403;
}
# 规则 5.2:sec-ch-ua 写的是 Chromium 而不是 Google Chrome
# 真实 Chrome 一定是 "Google Chrome";v="版本号"
if ($http_sec_ch_ua ~* "Chromium") {
return 403;
}
# 规则 5.3:组合规则(最准)
if ($http_accept_language = "en-US,en;q=0.9" && $http_sec_ch_ua ~ "Chromium") {
return 403;
}
# 规则 5.4:同 IP 多 JA3 检测(自定义 Lua 脚本)
# 60 秒内同一 IP 出现 JA3 数量 > 5 → 触发滑块
# 这个需要 WAF 支持 Lua/OpenResty,大部分百度云 WAF 不支持
# 替代方案:Nginx + lua 自行实现
效果预期:
- 112.82.218 段换 IP 也会被规则 5 拦下
- 因为这个工具的”DNA 指纹”是固定的,不会因为换 IP 而改变
规则 6:静态资源防盗链
# /file/script/ /skin/ /file/upload/ /lang/ 等
location ~* ^/(file/script|skin|file/upload|lang)/ {
# 只允许同域访问
valid_referers aifu360.com *.aifu360.com;
if ($invalid_referer) { return 403; }
# 强缓存
expires 7d;
add_header Cache-Control "public, immutable";
}
效果:
- 头条 Bytespider 等爬虫抓 page.js(Referer 是从外部搜索来的)直接 403
- 112.82.218 段跨域抓 zhanhui 资源也直接 403
规则 7:Bytespider 限速
# robots.txt(标准做法)
User-agent: Bytespider
Disallow: /
# WAF:对 Bytespider UA 单独限速
if ($http_user_agent ~* "Bytespider") {
# 60 秒超过 10 次 → 403
# 这是合法爬虫,但要限速避免被反爬侦察
}
六、配置前后的对比
配置前(原始数据)
| 指标 | 数值 |
|---|---|
| 总请求 | 72,239 |
| WAF 拦截 | 9,110(12.6%) |
| 漏放恶意请求(估算) | 8,000+ |
| 业务接口撞库 | 1,496+ 次 |
| 全站抓取 | 4,642+ 次 |
| 单 IP 1 秒最高 | 68 次 |
配置后(预估)
| 攻击类型 | 配置前 | 配置后(预估) |
|---|---|---|
| 42.187.x 段 | 6,121 次 | 0(整段封禁) |
| 220.181.51.x 段 | 1,150 次 | 0(整段封禁) |
| 112.82.218 段 | 4,672 次 | 0(规则 5 反指纹检测) |
| Firefox/32 群 | 1,496 次 | 0(规则 2 UA 黑名单) |
| Chrome/69 假浏览器 | 545 次 | 0(规则 2 + 规则 4) |
| 头条 Bytespider | 297 次 | 0(规则 6 防盗链) |
| 高频爬虫(1 分 5+ 次) | ~3,000 次 | 降 90%(规则 3 频次限速) |
| 撞库/撞 ID 枚举 | ~2,000 次 | 降 80%(规则 4 + 业务侧) |
预估拦截率从 12.6% 提升到 50~70%。
七、业务侧必须配合(光靠 WAF 远远不够)
WAF 解决的是”网络层”问题,业务层攻击光靠 WAF 拦不住。3 份日志里至少有 2 类问题必须业务侧解决:
7.1 /login.php 必须加图形验证码
现状:30+ IP 测 /login.php,每个 IP 只发 2~6 次请求。
- WAF 看不到单 IP 频次异常
- WAF 没法判断”这是撞库”还是”用户输错密码”
业务侧必须:
- 登录失败 3 次后,加图形验证码
- 同账号跨地区登录短信告警
- 异常登录 IP 段加黑(参考 145.223.131.214 这种商业代理)
7.2 /file/upload/ 必须加鉴权
现状:1,800+ 次文件 ID 暴力枚举。
- 文件是公开资源(WAF 不能直接拦)
- 但访问模式异常(同一 IP 几十次连续数字 ID)
业务侧必须:
- 改成 UUID 命名(没有规律可枚举)
- 非公开资源加鉴权(只有登录用户/文件 owner 能访问)
- 关键:不要用数字 ID!
7.3 /member/aifu360f_b.php 必须加风控
现状:1,496 次未授权访问,业务逻辑可能存在漏洞。
- 老 Firefox UA 反复试探
- GET 和 POST 都用,Referer 异常
业务侧必须:
- 加用户登录态校验
- 接口限速(单用户 1 分钟最多 10 次)
- 敏感操作(改密码、绑手机)二次验证
7.4 静态资源必须走 CDN
现状:112.82.218 单 IP 占总带宽 38%。
- WAF 限速会误伤真实用户
- 静态资源本来就是给浏览器缓存的,不需要源站扛
业务侧必须:
- 把
zhanhui.aifu360.com静态资源全部走 CDN aifu360.com主站的 css/js/png 也走 CDN- 走 CDN 后,源站只接 CDN 回源请求,流量压力会从 10 Mbps 降到 1 Mbps 以下
八、反思:从这次实战里学到的 5 件事
8.1 WAF 策略不是一次配好就完事
3 份日志展示了一个完整的攻击升级链路:
- 第一份日志:基础攻击(IP 段、UA 异常)
- 第二份日志:反指纹攻击(112.82.218 段)
- 第三份日志:业务层撞库(Chrome/69 测 /login.php)
WAF 规则必须跟着攻击者持续迭代,一周 review 一次日志,新增攻击者立刻加规则。
8.2 攻击者比想象中更专业
112.82.218 段这个攻击者:
- 71 个 JA3 反指纹(技术含量很高)
- 知道 TLS 1.3 + HTTP/2 + 加密套件的”标准化”
- 故意把 UA 写得像真实 Chrome
- 唯一破绽是
accept-language=en-US和sec-ch-ua里把Google Chrome写成Chromium
专业的攻击者也会露出破绽,关键是要看得够细。
8.3 业务层攻击 WAF 看不见
撞库、ID 枚举、漏洞探测——这些攻击的请求”看起来正常”,WAF 不知道是用户在登录还是在撞库。业务层风险必须业务层解决。
8.4 频次限速是最普适的规则
不管攻击者怎么换 IP、换 JA3、换 UA,频次限速拦不住就奇怪了。这应该是 WAF 默认开启的第一规则。
8.5 数据本身会说话
整个分析过程,90% 的时间是在看数据——看时间分布、看 IP 集中度、看 UA 模式、看路径规律。好日志比好工具更重要。
百度云 WAF 的日志格式设计得很清晰(final_action / final_module / final_rule_id / JA3/JA4 / 时间戳 / 字节数),让分析变得可行。如果你的 WAF 日志没有这些字段,赶紧要求厂商加上。
九、后续加固清单(优先级排序)
🔴 P0(本周内完成)
- [ ] IP 黑名单:42.187.132.0/24 / 42.187.135.0/24 / 42.187.138.0/24 / 220.181.51.0/24 / 112.82.218.0/24
- [ ] Firefox/32 老 UA 全量 IP 黑名单(60+ 个)
- [ ]
/login.php加图形验证码 - [ ] UA 黑名单:Chrome/60-69 + Mac OS X 10_13 组合规则
- [ ] 频次限速:1 分钟 >30 次触发滑块
🟡 P1(2 周内)
- [ ] 静态资源走 CDN
- [ ]
/file/upload/改 UUID 命名 - [ ]
/member/接口加用户登录态校验 - [ ] Bytespider robots.txt 限制
- [ ] 业务侧风控:异地登录告警
🟢 P2(1 个月内)
- [ ] 自研 WAF 规则:同 IP 多 JA3 检测(对抗反指纹)
- [ ] 自研:基于 Host + Referer + UA 的”指纹稳定性”评分
- [ ] 业务日志接入 SIEM,做关联分析
- [ ] 月度安全报告自动化生成
附录:完整封禁清单
A.1 IP 段封禁(整段)
42.187.132.0/24 # 天津 IDC,文件枚举
42.187.135.0/24 # 天津 IDC,文件枚举
42.187.138.0/24 # 天津 IDC,文件枚举
220.181.51.0/24 # 百度云假爬虫
112.82.218.0/24 # 反指纹全站抓取
A.2 Firefox/32 攻击者群单 IP 封禁
# 日志 1-3 累计超过 20 次的 IP
223.72.43.43 # 376 次(累计攻击升级)
120.7.16.33 # 197 次
112.21.2.68 # 161 次
114.227.173.48 # 98 次
114.225.89.35 # 200+ 次
116.235.8.202 # 61 次
111.31.251.151 # 59 次
120.7.17.84 # 52 次
39.166.43.2 # 52 次
14.153.12.28 # 51 次
183.241.164.165 # 45 次
116.4.235.67 # 38 次
223.87.198.144 # 48 次
182.110.100.222 # 34 次
183.198.30.194 # 32 次
112.47.172.103 # 24 次
112.81.141.187 # 26 次
122.97.172.2 # 24 次
180.115.253.184 # 24 次
117.162.167.182 # 27 次
A.3 头条 Bytespider GCP 段
34.92.0.0/16 # GCP,Bytespider 部署
35.220.0.0/16 # GCP
34.96.0.0/16 # GCP
35.241.0.0/16 # GCP
# 注:这些是 GCP 通用段,真要封要慎重,建议先 robots.txt 限速
A.4 商业代理 IP 段
145.223.0.0/16 # 商业代理,撞库常用
84.75.0.0/16 # 商业代理
A.5 高风险单 IP(单次封禁)
# Chrome/69 假浏览器撞库(日志 3 出现,30+ IP 随机)
# 完整 IP 太多,建议加 UA 规则而不是 IP 规则
# 头条爬虫高频
34.92.42.23
35.220.163.44
34.92.23.141
35.220.143.152
34.96.236.98
34.96.161.202
34.92.189.90
A.6 WAF 自定义规则(可直接复制粘贴)
# 1. UA 黑名单(对抗老版本浏览器和工具)
if ($http_user_agent ~* "Firefox/3[0-9]\.") { return 403; }
if ($http_user_agent ~* "Chrome/(4[5-9]|5[0-9]|6[0-9]|7[0-9])\.") { return 403; }
if ($http_user_agent ~* "MSIE [1-8]\.") { return 403; }
if ($http_user_agent ~* "Android [1-6]\.") { return 403; }
if ($http_user_agent ~* "Mac OS X 10_1[0-3]") { return 403; }
if ($http_user_agent ~* "(python-requests|curl|wget|scrapy|Go-http-client|okhttp)") { return 403; }
# 2. 业务接口专项(/login.php)
location = /login.php {
if ($http_user_agent ~* "OS X 10_13.*Chrome/69") { return 403; }
limit_req zone=login burst=3 nodelay;
}
# 3. /member/ 接口
location ~* ^/member/ {
if ($http_user_agent ~* "Firefox/3[0-9]") { return 403; }
limit_req zone=member burst=5 nodelay;
valid_referers aifu360.com *.aifu360.com;
if ($invalid_referer) { return 403; }
}
# 4. 静态资源防盗链
location ~* ^/(file/script|skin|file/upload|lang)/ {
valid_referers aifu360.com *.aifu360.com;
if ($invalid_referer) { return 403; }
expires 7d;
add_header Cache-Control "public, immutable";
}
# 5. 反指纹检测(对抗 112.82.218 段)
if ($http_accept_language = "en-US,en;q=0.9" && $http_sec_ch_ua ~ "Chromium") {
return 403;
}
写在最后
WAF 不是银弹,但用好 WAF + 配合业务层防护 + 持续迭代规则,能挡掉 90% 以上的攻击者。
记住:专业的攻击者会换 IP、换 JA3、换 UA,唯一不变的是他们的行为模式。看日志,抓行为,建规则,跟迭代——这就是 WAF 运维的全部。
如果你也想用同样的方法分析自己网站的 WAF 日志,重点关注 4 个字段:
final_action/final_module/ja3_hash/ja4_hash。有这 4 个字段,基本能看出 80% 的攻击。完整源代码和分析脚本可以参考这篇文章的实现,逻辑不复杂,关键是耐心看数据。
作者介绍:Mavis,从业 8 年的安全运维工程师,擅长 WAF 策略调优和反爬虫对抗。这篇文章基于真实事件复盘,所有数据脱敏后呈现。
版权:CC BY-NC 4.0
