brianbrandson/ctf-dahua-ptz

GitHub: brianbrandson/ctf-dahua-ptz

一个基于 Docker 部署的 IoT/Web 安全 CTF 挑战项目,模拟 Dahua PTZ 摄像头漏洞评估,要求玩家利用泄露凭证和 API 文档完成多步骤攻击链以获取 flag。

Stars: 0 | Forks: 0

# CTF 挑战:无人机靶场摄像头 ### “大师 GCP 恢复行动” **类别:** Web / 脚本编程 / 物联网安全 **难度:** 中等 **技术:** OSINT、Hash 破解、API 枚举、HTTP Session 篡改 dahua-login ## 概述 本挑战模拟了对守护无人机校准场地的 **Dahua PTZ(云台变焦)摄像头** 的漏洞评估。玩家将扮演一名投机者,获得了一个包含内部文档和聊天记录的“技术员包”。 **目标:** 利用泄露的凭证和 API 文档对摄像头进行身份验证,克服特定的固件怪癖(模拟漏洞),找到场地中隐藏的标记(大师 GCP),并获取 flag。 ## 部署与设置 该挑战完全使用 Docker 进行容器化。 ### 前置条件 - Docker & Docker Compose - Git ### 快速开始 1. **克隆代码仓库:** git clone https:/github.com/brianbrandson/ctf-dahua-ptz.git cd ctf-dahua-ptz 2. **启动环境:** docker-compose up -d --build 3. **验证访问:** - Web 界面:`http://:8080`(Dahua 风格的登录页面) - API Endpoint:`http://:8080/cgi-bin/magicBox.cgi?action=getSystemInfo` ### 配置 关键设置 —— 均可通过 `docker-compose.yml` 中的环境变量进行配置: | 变量 | 默认值 | 描述 | |---|---|---| | `CTF_FLAG` | `BSIDES{FLAG_NOT_CONFIGURED}` | 玩家提交给 CTFd 的静态 flag | | `SECRET_KEY` | (不安全的默认值) | 签名 Digest Auth nonces —— 在活动前进行轮换 | | `DISCORD_WEBHOOK_URL` | _(空)_ | 用于解题通知的 Webhook URL | | `NIGHT_MODE` | `true` | 设置为 `false` 可完全禁用夜间滤镜 | | `TZ` | `Europe/Vilnius` | 夜间模式和 OSD 时间戳的时区 | 在 `app.py` 中硬编码(如有需要可直接编辑): - **`FLAG_PRESET`**:包含 flag QR 的 Preset ID(默认:`283`)。 - **`VALID_USER` / `VALID_PASS`**:摄像头凭证(默认:`dave` / `solar99`)。 ## 仓库结构 ``` . ├── app.py # Core Flask application (Firmware simulation) ├── docker-compose.yml # Container orchestration ├── Dockerfile # Python environment build ├── files/ # Player Artifacts (The "Leaked" USB drive) │   ├── Dahua_HTTP_API_V2.84.pdf # Real API docs │   ├── incident_report_882_chat.md # Hints & Hash │   ├── READ_ME_FIRST.md # Player Mission Briefing │   ├── site_installation_notes.md # Camera on site hints │   └── technician_pack.zip # Downloadable zip for players ├── admin/ # Documentation │   └── OPS_MANUAL.md # Ops & Admin Manual ├── tools/ # Admin Tools │ └── solver/ # Automated Verification Script │ ├── solver.py │ └── requirements.txt ├── images/ # Camera feed assets (400 presets) ├── templates/ # Web UI templates │ ├── login.html # Dahua-styled login page │ └── dashboard.html # Live camera dashboard ├── requirements.txt # Python dependencies └── SOLUTIONS.md # Walkthrough & Answer Key (SPOILERS) ``` ## 解答 有关完整的分步指南、答案和自动化解题脚本,请参阅 **[SOLUTIONS.md](SOLUTIONS.md)**。 ## 活动后记(BSides Vilnius 2026) 该挑战在整个活动期间(2026 年 5 月 31 日至 6 月 4 日)于一台 Hetzner CX33 VPS 上成功运行,未出现任何停机。对于想要重新部署此项挑战的人,有以下几点值得了解: ### 性能:过大的模板 `login.html` 和 `dashboard.html` 各自嵌入了多张内联 base64 图片(分别约为 3.3 MB 和 3.4 MB)。在仅使用单个 Gunicorn worker(这是共享内存 session 状态所必需的)的情况下,每次页面加载都会使约 3 MB 的数据串行通过该进程 —— 当多个玩家同时在线时,速度会明显变慢。 **下次部署的修复方案:** 将内联 base64 图片移至 Flask 的 `static/` 文件夹中,并通过 `{{ url_for('static', filename='...') }}` 进行引用。Gunicorn 能高效地提供静态文件服务,且浏览器会对其进行缓存;模板大小应该只有几 KB,而不是几 MB。 ### AI 解题观察 Claude Code (Sonnet) 在无人交互的情况下自主挑战了该线上挑战 —— 使用了与所有人相同的玩家文件(`technician_pack.zip` 和任务简报)。它成功破解了 hash,通过 HTTP Digest Auth 完成了身份验证并保持了正确的 session 持久性,还枚举了预设以找到被遮蔽的预设。它在最后一步卡住了:它从未被告知其中涉及 QR 码,因此它获取了快照但并未尝试对其进行解码。这很好地提醒了我们,AI agent 的能力受限于其获取的上下文 —— 缺少了心智模型中的某一块拼图,整个链条就会断裂。一个耗时 30 分钟的人类解题记录被怀疑有 AI 辅助的痕迹(一边使用脚本扫描预设,一边阅读 Dahua API PDF)。 ### 公共仓库说明 本仓库中的 `images/preset_283.jpg` 是一个**空白占位符** —— flag QR 码已被移除。在举办线上活动之前,请将您的 flag QR 合成到该图片(或任何其他预设)上,并在 `app.py` 中相应地更新 `FLAG_PRESET`。 **许可证:** MIT **作者:** Brian Brandson
标签:API枚举, Docker, IoT安全, StruQ, Web安全, 后端开发, 安全防御评估, 版权保护, 蓝队分析, 请求拦截, 逆向工具