一款实操型 AWS WAF 训练游戏,包含教程、计分实验和考试,玩家需编写 Web ACL 规则来拦截真实攻击形态,同时避免误报。
一个通过防御真实攻击来学习 AWS WAF 的实战训练游戏。
English | 日本語
致管理员:如何搭建环境、分发给参与者、运行以及清理,详见管理员指南(docs/ADMIN.md),面向参与者的分发材料为玩家入门指南(docs/PLAYER_GUIDE.md)。两份指南目前均为日文。
一个在攻击进行中学习 AWS WAF 的实战环境。
可单人游玩,也可与他人竞技。

从阅读教程中的攻击与步骤,到在漏洞实验室中设计规则、发起攻击、查看得分与参考答案,最后从管理页面开启一场竞赛的完整流程(约 70 秒)。更高画质的版本见 docs/demo-en.mp4。
录制于开发模式(
make dev),该模式使用参考答案而非真实的 AWS WAF 进行评分。
┌───────────────────── per player ──────────────────┐
Browser ── Lambda Function URL (gameapi: UI + API) │
│ async invoke │
▼ │
Lambda (trafficgen) ── HTTPS ─▶ ALB ◀── Web ACL (edited by the player)
│ │ │
│ ▼ │
│ Lambda (targetapp: dummy online shop) │
▼ └────────────────────────────────────┘
DynamoDB (runs, best scores, locks)
wafdojo-<name>-cf,us-east-1)。CloudFront 直接代理虚拟应用的 Lambda Function URL 而不是 ALB,因此 ALB 的 Web ACL 规则在那里不适用。设置 enable_cloudfront = false 可跳过它。X-Forwarded-For 中用文档地址(RFC 5737)表示(假设站点位于 CDN 之后)。| ID | 主题 | 你将学到 |
|---|---|---|
| tutorial-1-sqli | SQL 注入 | 托管规则组 |
| tutorial-2-xss | 评论表单中的 XSS | 自定义规则(规则构建器)、请求体检查、文本转换 |
| tutorial-3-ipset | 威胁列表中的 IP | IP 集、CIDR、X-Forwarded-For |
| tutorial-4-useragent | 漏洞扫描器 | 对请求头进行字符串匹配、OR 语句、小写转换 |
| tutorial-5-ratelimit | 来自单个 IP 的洪水攻击 | 基于速率的规则、聚合键 |
| tutorial-6-ja4 | 伪装成浏览器的爬虫 | JA4 指纹的工作原理以及如何解读它们(a_b_c)、精确 JA4 匹配、WAF 日志分析 |
| ID | 主题 | 你将学到 |
|---|---|---|
| game-1-fakebot | 伪装成 Googlebot 的爬虫 | 组合 AND / NOT(UA 声称是 Googlebot 且 IP 不是 Google 的) |
| game-2-admin | 从外部访问管理面板 | URI 路径条件 + IP 允许列表、大小写敏感性 |
| game-3-traversal | 路径遍历 | 叠加文本转换(双重解码)、避免误报 |
| game-4-cms | 一条阻止你编辑的 XSS 规则 | 构建例外、规则优先级、重新审视现有规则 |
| game-5-bruteforce | 登录暴力破解 + 企业 NAT | 缩小范围语句、阈值设计 |
| game-6-ja4regex | 不断调整其 JA4 的机器人军团 + 使用同一库的合作伙伴 | JA4 正则表达式(捕获共享的 b 部分)、为未见过的变体做准备、使用 AND NOT 的例外 |
你在教程中创建的规则会保留在原处,因此在游戏模式中它们有时会导致误报(第 4 和第 5 阶段)。你需要重新审视现有规则,而不仅仅是阻止新的攻击。
每个挑战的内容是:“一个新漏洞出现了。它可以在这些条件下被阻止。编写规则。”目标是让你在出现新漏洞时能够编写自己的规则。尝试一次后,你可以看到标准答案规则 JSON(可直接粘贴到控制台的 Rule JSON 编辑器中)和解释。许多 Level 2 和 Level 3 挑战还包含一条“常见陷阱”规则以及它为何失败。
| 级别 | 内容 | 挑战 |
|---|---|---|
| 级别 1:遵循公告 | 将明确说明要检查什么、如何匹配以及确切字符串的指导转化为精确规则 | Log4Shell、Spring4Shell、Shellshock、Confluence OGNL、F5 BIG-IP iControl REST、Next.js 中间件绕过、Apache HTTP Server 路径遍历、Text4Shell、Metabase GeoJSON (CVE-2021-41277)、ProxyLogon (CVE-2021-26855)、Confluence Velocity (CVE-2023-22527) |
| 级别 2:将公告转化为 WAF 规则 | 根据文字描述的条件,自行选择被检查的组件、转换方式和匹配类型 | PHP-CGI (CVE-2024-4577)、Citrix ADC、FortiOS SSL-VPN、WebLogic 控制台、Confluence 安装向导、Spring Cloud Function、Struts 2 S2-045、vCenter vROps、XXE、GraphQL introspection、ProxyNotShell、CRLF 注入、X-Original-URL、F5 BIG-IP TMUI (CVE-2020-5902)、TeamCity (CVE-2024-27198) |
| 级别 3:从 PoC 中推导规则 | 没有缓解指导。找出攻击的本质,并为两种变体和误报做好准备 | 混淆的 Log4Shell、SSRF(元数据)、SSTI、操作系统命令注入、原型污染、开放重定向、文件上传、PAN-OS GlobalProtect (CVE-2024-3400)、阅读原始公告:Ivanti Connect Secure (CVE-2023-46805 / CVE-2024-21887)、GitLab (CVE-2023-7028) |
| 级别 4:托管规则与 WAF 的局限 | 当托管规则阻止合法流量时,在保持防护的同时修复它(按规则 Count 覆盖 + 标签匹配)。为 WAF 自身的局限做好准备,例如请求体检查限制 | 核心规则集 SizeRestrictions_BODY(大文件上传)、NoUserAgent_HEADER(IoT 设备)、GenericRFI_QUERYARGUMENTS(内部 webhook 工具)、8 KB 限制(请求体检查限制与超大请求处理;在 ALB 上固定为 8 KB)、将 CloudFront 的 16 KB 限制扩展到 64 KB(在玩家自己的 CloudFront 上实际体验) |
这些挑战培养的能力:
__typename、/mgmt-news 或 ${name})攻击请求是对真实攻击形态的无害复现,所有外部目标都使用保留域名,例如 attacker.example。
go test ./... 检查所有 46 个实验、考试和运维挑战的模型答案是否拦截了每一次攻击且不拦截任何合法请求(internal/wafrule 中的评估器在本地复现了 AWS WAF 的匹配行为)。mkdir -p /tmp/rules && WAFDY_EXPORT_RULES=/tmp/rules go test -run TestExportLabRules ./internal/scenario/
for f in /tmp/rules/*.json; do aws wafv2 check-capacity --scope REGIONAL --cli-binary-format raw-in-base64-out --rules file://$f; done
仅 Level 4 使用的核心规则集就消耗 700 WCU。实验模型答案合计约 1,000 WCU,再加上教程和游戏规则,已接近 Web ACL 上限(默认 1,500 WCU)。删除已掌握挑战的规则可保留你的记录。
Level 4 托管规则在评估器中依据 AWS 公布的规则描述复现(实际内容未公开,因此并非精确复现)。规则和标签名称已通过 AWS 的 DescribeManagedRuleGroup API 与真实名称核对确认。
与真实运维一样,你先用 Count 规则进行一次“侦察”(不计分),研究 WAF 日志,然后进行正式运行。
| 挑战 | 内容 |
|---|---|
| 找出误报元凶 | 从日志中找出触发你 XSS 规则的合法流量(合作伙伴的邮件模板同步),并划出例外。合法流量不会显示在屏幕上 |
| 从日志中识别机器人 | 在 Logs Insights 中聚合 /login 请求,找出撞库机器人的 JA4。JA4 不会显示在屏幕上 |
测试会发送你尚未见过的实验攻击变体。照抄实验模型答案无法通过。
| 挑战 | 内容 |
|---|---|
| Log4Shell 变体 | Log4Shell 出现在标头、查询或正文中的任意位置,使用嵌套、双重编码和 JSON 转义 |
| 路径遍历大巡游 | 路径、查询、Cookie 和 JSON 中的遍历,涵盖 Linux 和 Windows 风格及各种编码 |
| 必须紧闭的门 | 访问 .git、.env、actuator 等,通过大写、重复斜杠、../ 绕行、; 和编码 |
通关所有教程,并在其余全部 52 个挑战(6 个游戏、41 个实验、3 个考试、2 个运维)中得分 80 或以上,即可在大厅和排行榜上显示为 🏅 WAF 专家。
在 internal/scenario/ 下的文件中调用 register(...)(实验则用 lab(level, ...))来添加场景。如果你还为实验编写模型答案,测试会自动验证其正确性。
管理员可以从管理页面开启竞赛(make admin 会打印其 URL):选择任意游戏、实验、运维或考试题目,并可设置可选的时间限制。每位玩家的屏幕都会切换到竞赛,他们可以立即解答所选题目,无需教程。允许使用提示(×0.8),竞赛结束后解锁模型答案,竞赛排行榜按玩家最佳分数之和排名(并列时先达到者优先)。竞赛分数与练习记录分开记录。详情请参阅管理员指南。
UI 支持日语和英语,可从页眉中的“Language”切换。初始选择跟随浏览器的语言设置,你的选择会保存在浏览器中。
要添加语言,请在三个位置添加:
internal/scenario/i18n.go 中的 Lang 和 Langsinternal/scenario/*.go 中的 T(...))和 API 消息(cmd/gameapi/main.go 中的 messages)。Text 是 map[Lang]string,因此你可以添加翻译,如 Text{Japanese: ..., English: ..., "ko": ...}cmd/gameapi/web/app.js 中的 I18N 和 LANG_NAMES)未翻译的文本会回退到英语,然后回退到日语。go test ./... 会检查场景和 API 消息中缺失的翻译。
score = 100 × attack block rate × (1 − false-positive rate) × 0.8 if you viewed hints