WeChall — IRC: Duckhunt

题目信息

  • 挑战: IRC: Duckhunt (#136)
  • 类型: Fun / Gaming
  • 作者: gizmore
  • 难度: 2
  • 解决人数: 53
  • 链接: https://www.wechall.net/en/challenge/irc/duckhunt/index.php

题目描述

Hello! IRC is not dead. Prove this theorem by reaching level 5 in #duckhunt.

连接 WeChall IRC 服务器,在 #duckhunt 频道玩 Duck Hunt 游戏,达到 level 5(140 XP)。Nickname 必须匹配 WeChall 用户名。

验证方式:挑战不再使用静态密码。提交时 WeChall 服务器通过 API https://wc3.wechall.net/duck_hunt/level.php?username=<username> 查询 IRC 等级。Level >= 5 即判定 solved。


技术分析

IRC 服务器

项目
Server irc.wechall.net:6697 (TLS 1.3)
IRCd InspIRCd-3
Channel #duckhunt
Bot Alfred (Eggdrop, Duck Hunt v2.11)
Topic No botting/scripting allowed \| unarmed? try !shop 5 or wait until 00:01

连接流程

  1. OpenSSL TLS 连接到 irc.wechall.net:6697
  2. 发送 NICK <username> + USER <username> 0 * :<username>(替换为 WeChall 用户名)
  3. 关键: 服务器在注册前发送 PING,必须回复 PONG :<token> 才能完成注册
  4. 等待 376 (End of MOTD) → 发送 JOIN #duckhunt
  5. 自动加入 #wechall(默认频道)+ #duckhunt

等级进度

Level Required XP Accuracy Reliability Ammo/Clip Clips
1 -4 55% 85% 6 2
2 20 56% 86% 6 2
3 50 57% 87% 6 2
4 90 58% 88% 6 2
5 140 59% 89% 6 2

每只鸭子 = 5 XP。弹药每日 00:01 UTC 重置。默认 12 发(2 clips × 6)。

Duck 检测:quack 变体列表

实测收集到的所有鸭子叫声变体(按出现频率排序):

变体 正则匹配 备注
KAAAAK K[A]{2,} 最常见
KAAAACK K[A]{2,}
KAAACK K[A]{2,}
KWAK KWA[KC]?
KWAAK KWA[KC]?
KWAAACK KWA[KC]?
QUAC Q[UW]A{1,}C?K? 法语版
QWAAACK Q[UW]A{1,}C?K? 新变体
AAARK A{2,}RK 罕见
Hello world 机械鸭子(玩家 prank, 不射)

最终检测正则(覆盖所有已知变体,排除击杀结果/逃逸消息):

1
2
3
4
5
6
7
8
is_duck = (
nick == 'Alfred'
and re.search(r'K[A]{2,}|KWA[KC]?|Q[UW]A{1,}C?K?|A{2,}RK', clean, re.IGNORECASE)
and 'BANG' not in clean
and 'escapes' not in clean.lower()
and 'shot down' not in clean.lower()
and 'total of' not in clean.lower()
)

游戏状态消息

类型 模式 处理
击杀 shot down the duck in X.XXs hits++, ducks++
未命中 Missed. [missed: -1 xp] xp--
卡壳 *CLACK* Your gun is jammed 发送 !reload
空弹夹 *CLICK* EMPTY MAGAZINE 发送 !reload
逃逸 The duck escapes. 重置 duck_active
事故 accident xp 惩罚

弹药管理

  • 初始 2 chargers × 6 rounds = 12 发
  • 每日 00:01 UTC 自动重置
  • 枪卡壳/空弹夹后需要 !reload 命令
  • 商店物品 #2 (Extra clip, 20 XP) 可补充弹药
  • 商店物品 #21 (Bread, 2 XP) 提高鸭子频率
  • 商店物品 #10 (Four-leaf clover, 13 XP) 每只鸭子随机 +1~10 XP

Bot 实现

文件位置

1
2
3
4
5
6
<ctf-workspace>/challenges/wechall/duckhunt/
├── bot_v8.py # 最终版
├── bot_state.json # 进度持久化 (xp, level, shots, hits, ducks)
├── test_connect.py # IRC 连接测试
├── monitor.py # 频道监听诊断
└── bot.py ~ bot_v7.py # 各迭代版本

架构

  • subprocess.Popen 调用 openssl s_client 处理 SSL(绕过 Python socket 的代理问题)
  • 独立 reader 线程 + queue.Queue 非阻塞 I/O
  • 自动 PING/PONG 保活 + idle 超时重连
  • Duck 检测 → 自动射击(随机延迟 0.3-1.5s)
  • Jam/Empty → 自动 !reload
  • State 持久化 JSON
  • 断开自动重连(递增等待,最多 20 次)

运行方式

1
2
cd <ctf-workspace>
uv run python3 challenges/wechall/duckhunt/bot_v8.py

Daemon 化(VPS 上):

1
setsid python3 -u bot.py > bot.log 2>&1 < /dev/null &

实战记录

Vultr VPS 部署 (2026-07-16)

  • 实例: vc2-1c-0.5gb @ ewr (New Jersey), Debian 12
  • IP: 207.246.124.216
  • 运行时长: ~2 小时,然后销毁

进度

指标
运行时间 ~2h
射击次数 4
命中 1
击杀鸭子 2
XP 10
等级 1

遇到的问题和修复

  1. 注册 PING 未回复 → 在 NICK/USER 后立即处理 PING token
  2. Quack 变体不断发现 → 正则从 KAAACK 逐步扩展到覆盖 9 种变体
  3. 枪卡壳后停止射击 → 添加 !reload 自动处理
  4. SSH nohup & disown 不稳定 → 改用 setsid daemon 化
  5. 网络偶尔断开 → 自动重连机制

时间估算

以实测速率(~2 鸭子/小时,55% 命中率):

  • 140 XP = 28 只鸭子
  • 预计 12-20 小时连续运行
  • 建议 UTC 白天(06:00-18:00)运行,夜间鸭子休眠

剩余步骤

  1. 运行 bot_v8.py 直至 level 5
  2. 访问 https://www.wechall.net/en/challenge/irc/duckhunt/index.php(自动检测等级)
  3. 如需 VPS,使用 vultr-cli 创建实例并部署 bot

Vultr 快速部署

1
2
3
4
export VULTR_API_KEY='...'
vultr-cli instance create --region ewr --plan vc2-1c-0.5gb --os 2136 --label ctf-duckhunt
# 等待获取 IP,SSH 连接,上传 bot_v8.py,setsid 启动
# 完成后: vultr-cli instance delete <ID>

提交检查

1
2
3
# 查询当前等级
curl -sk 'https://wc3.wechall.net/duck_hunt/level.php?username=<username>'
# 返回值: {"error":0,"level":5} 表示成功(error=3 表示未注册)