每个应用程序以 4 个负载均衡的 Docker 容器运行,位于 nginx upstream 池之后,可通过虚拟机上的 nginx 反向代理访问。粘性会话确保有状态应用(Juice Shop、DVWA、VAmPI、CSD Demo)路由一致。所有应用程序均为故意存在漏洞的应用,专为安全测试设计。
在以下所有示例中,请将 <ORIGIN> 替换为 http://<PUBLIC_IP>。通过 Terraform 部署后,使用 terraform output -raw public_ip 获取 IP 地址。
| 路径 | 应用程序 | HTTP 方法 | 预期响应 |
|---|
/ | 落地页 | GET | 200 HTML,包含所有应用的链接 |
/health | 健康检查 | GET | 200 JSON {"status":"healthy","component":"origin-server",...} |
/juice-shop/ | Juice Shop | GET | 200 HTML(Angular SPA,约 75 KB) |
/juice-shop/rest/products/search?q= | Juice Shop API | GET | 200 JSON {"status":"success","data":[...]} (36 个产品) |
/dvwa/ | DVWA | GET | 302 重定向至 /dvwa/login.php |
/dvwa/login.php | DVWA 登录 | GET | 200 HTML 登录表单 |
/dvwa/setup.php | DVWA 设置 | GET | 200 HTML(首次运行数据库初始化) |
/vampi/ | VAmPI | GET | 200 HTML(API 文档) |
/vampi/users/v1 | VAmPI API | GET | 200 JSON {"users":[...]} |
/vampi/users/v1/register | VAmPI API | POST | 200 JSON {"status":"success",...} |
/vampi/users/v1/login | VAmPI API | POST | 200 JSON {"auth_token":"...","status":"success"} |
/httpbin/get | httpbin | GET | 200 JSON,包含请求详情 |
/httpbin/post | httpbin | POST | 200 JSON,包含已提交数据 |
/httpbin/headers | httpbin | GET | 200 JSON {"headers":{...}} |
/httpbin/status/:code | httpbin | GET | 返回指定的 HTTP 状态码 |
/whoami/ | whoami | GET | 200 纯文本,包含主机名、IP 及所有请求头 |
/csd-demo/ | CSD Demo | GET | 200 HTML,包含结账表单和攻击面板 |
/csd-demo/dashboard | CSD 攻击者视图 | GET | 200 HTML,显示已泄露数据 |
/csd-demo/health | CSD 健康检查 | GET | 200 JSON {"status":"healthy","component":"csd-demo",...} |
/csd-demo/exfil/log | CSD 泄露日志 | GET | 200 JSON 数组,包含已捕获数据 |
/dvga/ | DVGA GraphiQL | GET | 200 HTML(GraphiQL IDE) |
/dvga/graphql | DVGA GraphQL API | POST | 200 JSON GraphQL 响应 |
/restaurant/ | RESTaurant | GET | 200(重定向至文档) |
/restaurant/docs | RESTaurant Swagger | GET | 200 HTML(FastAPI Swagger UI) |
/restaurant/openapi.json | RESTaurant OpenAPI | GET | 200 JSON OpenAPI 规范 |
http://<PUBLIC_IP>:8888 | crAPI | GET | 200 HTML(SPA) |
http://<PUBLIC_IP>:8888/identity/api/auth/signup | crAPI 注册 | POST | 200 JSON |
http://<PUBLIC_IP>:8888/identity/api/auth/login | crAPI 登录 | POST | 200 JSON {"token":"..."} |
| |
|---|
| 路径 | /juice-shop/ |
| 镜像 | bkimminich/juice-shop:latest |
| 实例数 | 4 个(端口 3001-3004),通过 hash $cookie_token 实现粘性会话,代理缓存(60 秒 TTL) |
| 资源 | 每实例 2 CPU / 1 GiB RAM |
| 框架 | Node.js / Angular |
| 项目 | owasp.org/www-project-juice-shop |
OWASP Juice Shop 是目前最现代化且维护最活跃的漏洞 Web 应用程序。它在一个真实的电商应用中涵盖了整个 OWASP Top 10,包含 100 多个挑战。
| 场景 | 类别 | 攻击向量 |
|---|
| SQL 注入登录绕过 | WAF | 在登录邮箱字段输入 ' OR 1=1-- |
| 反射型 XSS | WAF、CSD | 通过搜索参数注入脚本 |
| 基于 DOM 的 XSS | CSD | URL 片段中的有效载荷 |
| 身份验证失效 | WAF | 暴力破解登录、JWT 篡改 |
| API 滥用 | API 安全 | 未授权访问 /api/ 端点 |
| 敏感数据泄露 | API 安全 | 未授权访问用户数据 |
| CSRF | WAF | 对个人资料修改发起跨站请求伪造 |
curl -s "http://<PUBLIC_IP>/juice-shop/" -o /dev/null -w "%{http_code}"
| |
|---|
| 路径 | /dvwa/ |
| 镜像 | 自定义 dvwa-fpm:latest(php-fpm + nginx,基于 ghcr.io/digininja/dvwa:latest 构建) |
| 实例数 | 4 个(端口 8101-8104),通过 hash $cookie_PHPSESSID 实现粘性会话 |
| 资源 | 每实例 0.5 CPU / 256 MiB RAM |
| 数据库 | 共享 MariaDB 10.11(dvwa-db 容器,1 CPU / 768 MiB) |
| 框架 | PHP 8 / php-fpm / MariaDB |
| 凭据 | admin / password |
DVWA 是 WAF 测试的行业标准。它具有可调节的安全级别(低、中、高、不可能),逐步增加输入验证和输出编码。
| 场景 | 类别 | 安全级别 |
|---|
| SQL 注入 | WAF | 低:简单 ' OR 1=1#;高:盲注 |
| 命令注入 | WAF | 低:; ls;高:过滤特殊字符 |
| 文件包含 | WAF | 低:直接路径遍历;高:已过滤 |
| XSS(反射型) | WAF、CSD | 低:基础 <script>;高:编码绕过 |
| XSS(存储型) | WAF、CSD | 低:留言板中的持久化脚本 |
| 文件上传 | WAF | 低:上传 PHP 木马;高:扩展名过滤 |
| 暴力破解 | 机器人防御 | 自动化登录尝试 |
登录后在 /dvwa/security.php 设置安全级别:
- 低 — 无输入验证。所有攻击均有效。适合演示 WAF 签名。
- 中 — 基础过滤。部分攻击需要编码或绕过技术。
- 高 — 强过滤。仅高级技术可成功。适合展示 WAF 局限性。
- 不可能 — 完全安全的实现。演示正确的防御性编码方式。
DVWA 在首次部署后需要进行一次性数据库设置:
- 访问
http://<PUBLIC_IP>/dvwa/setup.php
- 点击 Create / Reset Database
- 使用
admin / password 登录
| |
|---|
| 路径 | /vampi/ |
| 镜像 | erev0s/vampi:latest,使用 gunicorn 入口点(4 个 worker) |
| 实例数 | 4 个(端口 5101-5104),通过 ip_hash 实现粘性会话(每实例独立 SQLite) |
| 资源 | 每实例 0.5 CPU / 512 MiB RAM |
| 框架 | Python / Flask / gunicorn |
| 项目 | github.com/erev0s/VAmPI |
VAmPI 专为测试 OWASP API 安全 Top 10 而构建,提供一个具有故意漏洞的真实 REST API。每个实例运行 4 个 gunicorn worker 并拥有独立的 SQLite 数据库。ip_hash 粘性会话确保来自同一客户端 IP 的注册和登录请求始终路由到同一实例。
| 场景 | OWASP API Top 10 | 方法 |
|---|
| 对象级别授权失效(BOLA) | API1 | 通过篡改 ID 访问其他用户数据 |
| 身份验证失效 | API2 | 弱令牌处理、无速率限制 |
| 过度数据暴露 | API3 | API 返回超出客户端所需的数据 |
| 批量赋值 | API6 | 通过意外参数修改管理员字段 |
| SQL 注入 | API8 | 通过 API 参数进行注入 |
| 资产管理不当 | API9 | 未记录的 API 端点 |
curl -X POST "http://<PUBLIC_IP>/vampi/users/v1/register" \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test123","email":"test@test.com"}'
curl -X POST "http://<PUBLIC_IP>/vampi/users/v1/login" \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test123"}'
curl "http://<PUBLIC_IP>/vampi/users/v1"
| |
|---|
| 路径 | /httpbin/ |
| 镜像 | kennethreitz/httpbin:latest,使用 gunicorn CMD 覆盖(-w 4 -k gevent --timeout 30) |
| 实例数 | 4 个(端口 8201-8204),轮询方式(无状态) |
| 资源 | 每实例 0.5 CPU / 256 MiB RAM |
| 框架 | Python / Flask / gunicorn + gevent |
| 项目 | httpbin.org |
httpbin 是一个简单的 HTTP 请求/响应服务,适用于基础 API 演示、测试请求头以及验证代理行为。
| 端点 | 用途 |
|---|
/httpbin/get | 返回 GET 请求数据(请求头、参数、来源 IP) |
/httpbin/post | 返回 POST 请求数据(请求体、表单、JSON) |
/httpbin/headers | 返回请求头 |
/httpbin/ip | 返回来源 IP |
/httpbin/user-agent | 返回 User-Agent 请求头 |
/httpbin/status/:code | 返回指定的 HTTP 状态码 |
/httpbin/delay/:seconds | 延迟 N 秒后响应 |
/httpbin/anything | 返回请求中传入的任何内容 |
# 查看源站收到的请求头(用于验证 F5 XC 请求头注入)
curl -s "http://<PUBLIC_IP>/httpbin/headers" | jq .
curl -s -o /dev/null -w "%{http_code}" "http://<PUBLIC_IP>/httpbin/status/403"
whoami 是 Traefik 的轻量级请求回显服务器。它以源站视角展示传入 HTTP 请求的每项详情 — 主机名、IP 地址、所有请求头、方法和 URL。这是验证 F5 XC 是否正确注入请求头时最重要的诊断工具。
| 使用场景 | 关注内容 |
|---|
| 验证 F5 XC 请求头注入 | X-Forwarded-For、True-Client-IP、X-Volterra-* 请求头 |
| 确认客户端 IP 可见性 | X-Real-IP 与 RemoteAddr 的对比 |
| 调试 WAF 误报 | 比较 F5 XC 前后的请求头 |
| 验证机器人防御标记 | X-Volterra-Bot-Type、X-Volterra-Bot-Verified 请求头 |
| 检查 TLS 终止 | 当 TLS 在 F5 XC 终止时,X-Forwarded-Proto 显示 https |
curl "http://<PUBLIC_IP>/whoami/"
# 模拟通过 F5 XC 的请求(携带注入的请求头)
curl "http://<PUBLIC_IP>/whoami/" \
-H "X-Forwarded-For: 203.0.113.50" \
-H "True-Client-IP: 203.0.113.50" \
-H "X-Forwarded-Proto: https"
示例输出:
RemoteAddr: 172.17.0.1:55118
True-Client-Ip: 203.0.113.50
X-Forwarded-For: 203.0.113.50, 10.0.0.1
X-Real-Ip: 104.219.105.84
DVGA 专为测试 GraphQL 特有漏洞而构建。它在 /dvga/ 提供 GraphiQL IDE 用于交互式查询探索,在 /dvga/graphql 提供 GraphQL API 端点。每个实例使用独立的 SQLite 数据库,因此 ip_hash 粘性会话确保状态一致性。
| 场景 | 类别 | 攻击向量 |
|---|
| GraphQL 注入 | API 安全 | 通过字符串插值执行恶意查询 |
| 拒绝服务 | API 安全 | 深度嵌套查询、批量查询、资源耗尽 |
| 授权绕过 | API 安全 | 通过 GraphQL 访问未授权数据 |
| 信息泄露 | API 安全 | 内省查询暴露 Schema 详情 |
| 批量攻击 | API 安全 | 在单个请求中执行多个操作 |
curl -sf "http://<PUBLIC_IP>/dvga/" -o /dev/null -w "%{http_code}"
curl -s "http://<PUBLIC_IP>/dvga/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{ __schema { types { name fields { name } } } }"}'
curl -s "http://<PUBLIC_IP>/dvga/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{ pastes { title content } }"}'
curl -s "http://<PUBLIC_IP>/dvga/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"mutation { createPaste(title:\"test\", content:\"hello\", public:true) { paste { title } } }"}'
| |
|---|
| 路径 | /restaurant/ |
| 镜像 | 基于 theowni/Damn-Vulnerable-RESTaurant-API-Game 自定义构建 |
| 实例数 | 4 个(端口 8301-8304),轮询方式(共享 PostgreSQL) |
| 资源 | 每实例 0.5 CPU / 256 MiB RAM |
| 数据库 | 共享 PostgreSQL 15.4(restaurant-db 容器,0.5 CPU / 512 MiB) |
| 框架 | Python / FastAPI / PostgreSQL |
| 凭据 | admin / password(PostgreSQL) |
| 项目 | github.com/theowni/Damn-Vulnerable-RESTaurant-API-Game |
RESTaurant 是一个覆盖 OWASP API 安全 Top 10 2023 的游戏化漏洞 REST API。它使用 FastAPI,并在 /restaurant/docs 提供自动生成的 Swagger UI 文档。所有 4 个实例共享一个 PostgreSQL 数据库,因此轮询负载均衡无需粘性会话即可正常工作。
| 场景 | OWASP API Top 10 2023 | 方法 |
|---|
| 对象级别授权失效(BOLA) | API1 | 通过篡改 ID 访问其他用户的订单 |
| 身份验证失效 | API2 | 弱令牌处理、凭据填充 |
| 对象属性级别授权失效 | API3 | 对用户资料字段进行批量赋值 |
| 无限制资源消耗 | API4 | 端点无速率限制 |
| 功能级别授权失效(BFLA) | API5 | 以普通用户身份访问管理员端点 |
| 服务端请求伪造(SSRF) | API7 | 篡改服务端 URL 请求 |
| 安全配置错误 | API8 | 冗余错误信息、默认凭据 |
curl -sf "http://<PUBLIC_IP>/restaurant/docs" -o /dev/null -w "%{http_code}"
curl -s "http://<PUBLIC_IP>/restaurant/openapi.json" | jq .info
# BOLA -- 访问其他用户的订单(需认证后操作)
curl -s "http://<PUBLIC_IP>/restaurant/orders/1" \
-H "Authorization: Bearer <token>"
curl -s -X POST "http://<PUBLIC_IP>/restaurant/admin/users" \
-H "Authorization: Bearer <user_token>" \
-H "Content-Type: application/json"
| |
|---|
| 端口 | 8888(专用端口 — 不使用路径前缀) |
| 镜像 | crapi/crapi-web、crapi/crapi-identity、crapi/crapi-community、crapi/crapi-workshop、PostgreSQL、MongoDB、MailHog |
| 实例数 | 7 个微服务(每个服务单实例) |
| 资源 | 总计约 3.0 CPU / 约 2.0 GiB RAM |
| 框架 | React SPA + Java/Go/Python 微服务 |
| 项目 | github.com/OWASP/crAPI |
crAPI 是 OWASP 在 API 安全测试领域的旗舰项目。它以 7 个微服务的形式运行在专用端口(8888)上,原因是 React SPA 硬编码了 API 路径,无法在路径前缀后提供服务。网络安全组已允许端口 8888 的入站流量。
MailHog 捕获 crAPI 发送的所有邮件(账户验证、密码重置)。通过 SSH 隧道在端口 18025 访问 MailHog。
| 类别 | 漏洞 |
|---|
| BOLA(对象级别授权失效) | 访问其他用户的车辆、订单和报告 |
| BFLA(功能级别授权失效) | 提升至管理员权限、访问受限端点 |
| 批量赋值 | 通过 API 修改受保护字段(角色、余额) |
| SSRF(服务端请求伪造) | 操纵服务端 URL 获取行为 |
| JWT 篡改 | 伪造或修改 JWT 令牌以进行权限提升 |
| NoSQL 注入 | 向 MongoDB 支持的端点注入查询 |
| 过度数据暴露 | API 返回敏感用户数据 |
curl -sf "http://<PUBLIC_IP>:8888" -o /dev/null -w "%{http_code}"
curl -s -X POST "http://<PUBLIC_IP>:8888/identity/api/auth/signup" \
-H "Content-Type: application/json" \
-d '{"name":"Test User","email":"test@example.com","number":"1234567890","password":"Test1234!"}'
curl -s -X POST "http://<PUBLIC_IP>:8888/identity/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"Test1234!"}'
# 访问 MailHog(通过 SSH 隧道进行邮件验证)
# ssh -L 18025:localhost:18025 azureuser@<PUBLIC_IP>
# 然后在浏览器中打开 http://localhost:18025
Port 8888 -> crapi-web (React SPA + nginx)
-> crapi-identity (Java, user auth, JWT)
-> crapi-community (Go, forums, posts)
-> crapi-workshop (Python, vehicle service)
-> crapi-postgres (PostgreSQL)
-> crapi-mailhog (email capture, port 18025)
| 演示场景 | 主要应用 | 辅助应用 |
|---|
| WAF — SQL 注入 | DVWA | Juice Shop |
| WAF — XSS | DVWA | Juice Shop |
| WAF — 命令注入 | DVWA | — |
| API 安全 — BOLA | VAmPI | — |
| API 安全 — 认证绕过 | VAmPI | Juice Shop |
| API 安全 — 数据暴露 | VAmPI | httpbin |
| 机器人防御 — 暴力破解 | DVWA | Juice Shop |
| 机器人防御 — 爬虫抓取 | Juice Shop | — |
| 客户端防御 — DOM XSS | Juice Shop | — |
| 客户端防御 — 存储型 XSS | DVWA | Juice Shop |
| 客户端防御 — 卡片盗刷器 | CSD Demo | — |
| 客户端防御 — 表单劫持 | CSD Demo | — |
| 客户端防御 — 键盘记录器 | CSD Demo | — |
| 客户端防御 — 加密货币挖矿 | CSD Demo | — |
| 客户端防御 — DOM 劫持 | CSD Demo | — |
| API 安全 — GraphQL 注入 | DVGA | — |
| API 安全 — GraphQL DoS | DVGA | — |
| API 安全 — OWASP API Top 10 2023 | RESTaurant | crAPI |
| API 安全 — BFLA | RESTaurant | crAPI |
| API 安全 — 批量赋值 | crAPI | RESTaurant |
| API 安全 — SSRF | crAPI | RESTaurant |
| API 安全 — JWT 篡改 | crAPI | — |
| API 安全 — NoSQL 注入 | crAPI | — |
| 基础连通性测试 | httpbin | — |
| 请求诊断 | whoami | httpbin |
| 请求头注入验证 | whoami | — |