kaid0x/WSH-write-ups
GitHub: kaid0x/WSH-write-ups
该仓库提供了一场校内 CTF 比赛涉及 Web、密码学、逆向、取证等七大方向的 30 多道挑战题的官方详细题解。
Stars: 0 | Forks: 0
# WSH'26 (校内) — CTF 挑战题解
这是 WSH'26 —— 迪拜威斯敏斯特学校举办的首届校内 CTF 与 Hackathon 比赛中,涵盖 7 个类别的 30 多个挑战的官方题解。这些挑战旨在受控的、从入门到高级的环境中,教授真实的攻击技术。
## 📂 类别
| 类别 | 挑战数量 | 难度范围 |
|---|---|---|
| [Web 漏洞利用](#-web-exploitation) | 5 | 入门 → 高级 |
| [密码学](#-cryptography) | 6 | 入门 → 高级 |
| [逆向工程](#-reverse-engineering) | 5 | 中级 → 高级 |
| [数字取证](#-forensics) | 4 | 中级 → 高级 |
| [隐写术](#-steganography) | 4 | 中级 → 高级 |
| [OSINT](#-osint) | 5 | 入门 → 高级 |
| [杂项](#-misc) | 5 | 入门 → 高级 |
## 🌐 Web 漏洞利用
### WEB-01 — 芝麻开门! *(100 分)*
**考察知识点:** 隐藏的 HTML 注释
给了一个 QuantBit 员工门户网站的登录页面。没有提供凭证。
**解题步骤:**
- 查看页面源代码 (`Ctrl+U` / `Cmd+U`)
- 在 `` 部分找到隐藏的注释:
```
```
**FLAG:** `Flag{y0u_f0und_the_s3cr3t}`
### WEB-02 — 调试模式 *(160 分)*
**考察知识点:** 参数篡改
给了一个 QuantBit 知识库搜索页面。URL 栏显示了 `debug=false`。
**解题步骤:**
- 将 URL 参数从 `debug=false` 修改为 `debug=true`:
```
quantbit-solutions.io/kb?search=quantum&debug=true
```
- 此时会出现一个显示 flag 的调试面板
**FLAG:** `Flag{d3bug_m0d3_expos3d}`
### WEB-03 — 遗留痕迹 *(160 分)*
**考察知识点:** 暴露的备份文件
给了一个 QuantBit 员工门户网站的登录页面。没有提供凭证。
**解题步骤:**
- 查看页面源代码 —— 找到开发者注释:
```
```
- 访问 `/login.php.bak` —— 暴露了硬编码的凭证:
- 用户名:`sysadmin`
- 密码:`Qu@ntB1t_2026!`
- 使用这些凭证登录
**FLAG:** `Flag{b4ckup_f1l3s_4r3_d4ng3r0us}`
### WEB-04 — 隐藏在显眼处 *(200 分)*
**考察知识点:** 目录枚举
有一个正在运行的 Flask 开发者门户。提供了一个字典文件。
**解题步骤:**
```
gobuster dir -u http://[TARGET]:8080 -w wordlist.txt
```
- Gobuster 发现 `/dev-console` 返回 HTTP 200
- 访问 `/dev-console/internal` —— 页面上会显示 flag
**FLAG:** `Flag{g0bust3r_f0und_m3}`
### WEB-05 — 拦截我 *(200 分)*
**考察知识点:** 访问控制失效 / 参数篡改
有一个正在运行的 Flask 安全门户。提供的凭证为:`staff / staff123`。
**解题步骤:**
- 打开 Burp Suite → Proxy(代理) -> 打开 Intercept(拦截)
- 使用提供的凭证登录
- Burp 拦截了 POST 请求 —— 检查请求体:
```
username=staff&password=staff123&role=user
```
- 将 `role=user` 修改为 `role=admin`
- 转发请求 —— 加载带有 flag 的管理员仪表板
**FLAG:** `Flag{burp_1nt3rc3pt_pr1v3sc}`
## 🔐 密码学
### CRYPTO-01 — 迷失在翻译中 *(50 分)*
**考察知识点:** Base64 解码
**已知:** `RmxhZ3tiNHMzXzY0XzFzXzNhc3l9`
**解题步骤:**
- 打开 [CyberChef](https://gchq.github.io/CyberChef)
- 应用 "From Base64" 模块
**FLAG:** `Flag{b4s3_64_1s_3asy}`
### CRYPTO-02 — 旋转 *(50 分)*
**考察知识点:** ROT13
**已知:** `Synt{e0g13_1f_a0g_f3phe3}`
**解题步骤:**
- 在 [CyberChef](https://gchq.github.io/CyberChef) 或 [dcode.fr](https://dcode.fr/rot-13-cipher) 上应用 ROT13 解码
**FLAG:** `Flag{r0t13_1s_n0t_s3cur3}`
### CRYPTO-03 — 异或 *(150 分)*
**考察知识点:** 单字节 XOR 暴力破解
**已知:** `xord_flag.bin`
**解题步骤:**
```
with open('xord_flag.bin', 'rb') as f:
data = f.read()
for key in range(256):
decrypted = ''.join(chr(b ^ key) for b in data)
if 'Flag{' in decrypted:
print(f"Key: {key} -> {decrypted}")
```
密钥为 `0x4B`。
**FLAG:** `Flag{s1ngl3_byt3_x0r_crack3d}`
### CRYPTO-04 — 弱哈希 *(200 分)*
**考察知识点:** MD5 哈希破解
**已知:** `d8578edf8458ce06fbc5bb76a58c5ca4`
**解题步骤:**
- 将哈希值粘贴到 [crackstation.net](https://crackstation.net) 中
- 瞬间找到 —— 明文为 `qwerty`
**FLAG:** `Flag{qwerty}`
### CRYPTO-05 — Hashcat 时间 *(250 分)*
**考察知识点:** SHA256 字典攻击
**已知:** `000c285457fc971f862a79b786476c78812c8897063c6fa9c045f579a3b2d63f`
**解题步骤:**
```
echo "000c285457fc971f862a79b786476c78812c8897063c6fa9c045f579a3b2d63f" > hash.txt
hashcat -m 1400 -a 0 hash.txt /usr/share/wordlists/rockyou.txt
```
明文:`monkey`
**FLAG:** `Flag{monkey}`
### CRYPTO-06 — 损坏的 RSA *(350 分)*
**考察知识点:** 弱 RSA —— 小模数分解
**已知:** `n = 223453581498057202499787747366276011917`, `e = 65537`, `c = 97550082622071417773854378262669973112`
**解题步骤:**
```
from sympy import factorint
n = 223453581498057202499787747366276011917
factors = factorint(n)
# p = 17558207245877303381, q = 12726446291976903257
p, q = 17558207245877303381, 12726446291976903257
e = 65537
phi = (p-1)*(q-1)
d = pow(e, -1, phi)
c = 97550082622071417773854378262669973112
m = pow(c, d, n)
flag = m.to_bytes((m.bit_length()+7)//8, byteorder='big')
print(flag.decode())
```
**FLAG:** `Flag{rsa_pwn3d}`
## 🔧 逆向工程
### RE-01 — 附加字符串 *(120 分)*
**考察知识点:** 二进制字符串提取
**解题步骤:**
```
chmod +x strings_attached
strings strings_attached
```
Flag 以明文形式出现在输出中。
**FLAG:** `Flag{str1ngs_4r3_p0w3rful}`
### RE-02 — 十六进制里有什么? *(120 分)*
**考察知识点:** 十六进制转储分析
**解题步骤:**
```
xxd mystery.bin
```
Flag 出现在偏移量 `0x57` 处的 ASCII 列中。
**FLAG:** `Flag{h3x_dump_r3v34l5}`
### RE-03 — 修补我 *(250 分)*
**考察知识点:** 使用 radare2 进行静态二进制分析
**解题步骤:**
```
chmod +x patch_me
r2 ./patch_me
> aaa
> afl
> pdf @sym.check_password
```
字符串 `Qu4ntumB1t!` 在 `strcmp` 调用之前被加载。运行该二进制文件并在出现提示时输入它。
**FLAG:** `Flag{r4d4r3_4n4lys1s}`
### RE-04 — Java 秘密 *(280 分)*
**考察知识点:** Java 反编译 + XOR 解码
**解题步骤:**
```
jadx FlagChecker.jar
cat FlagChecker/sources/default-package/FlagChecker.java
```
`validateKey` 方法包含一个 XOR 编码的数组,密钥为 `7`:
```
keyBytes = [86, 114, 51, 105, 115, 114, 106, 69, 54, 115, 38]
print(''.join(chr(b ^ 7) for b in keyBytes))
# Output: Qu4ntumB1t!
```
**FLAG:** `Flag{j4dx_d3c0mp1l3d}`
### RE-05 — Ghidra 时间 *(350 分)*
**考察知识点:** 使用 Ghidra 进行剥离二进制文件逆向工程
**解题步骤:**
- 在 Ghidra 中打开二进制文件 → 分析
- 找到包含硬编码 XOR 字节数组的验证函数
- 逆向 XOR 转换(密钥:`13 + i`):
```
expected = [0x4b,0x62,0x6e,0x77,0x6a,0x75,0x7b,0x25,
0x71,0x64,0x23,0x47,0x6b,0x29,0x6d,0x2f,
0x6f,0x6d,0x2c,0x44,0x5c]
print(''.join(chr(b ^ ((13+i)%256)) for i,b in enumerate(expected)))
```
**FLAG:** `Flag{gh1dr4_r3v3rs3d}`
## 🔍 数字取证
### FORENSICS-01 — 显眼处的元数据 *(入门)*
**考察知识点:** EXIF 元数据分析
**解题步骤:**
```
exiftool vacation_photo.jpg
```
Flag 位于 `Comment` 字段中。
**FLAG:** `Flag{metadata_never_lies}`
### FORENSICS-02 — 可疑日志文件分析 *(中级)*
**考察知识点:** 日志分析 / 暴力破解检测
**解题步骤:**
```
grep "401" access.log | awk '{print $1}' | sort | uniq -c | sort -rn
grep "185.220.101.47" access.log
```
其中一个 IP 有 25 次失败的登录尝试。其成功登录之后紧接着是一个对 `/admin/config_backup.php?token=` 的 GET 请求。
**FLAG:** `Flag{brute_force_left_a_trail}`
### FORENSICS-03 — DNS 隧道 *(高级)*
**考察知识点:** Wireshark 中的隐蔽通道分析
**解题步骤:**
- 在 Wireshark 中打开 `dns_challenge.pcap` → 过滤器:`dns`
- 发现对 `*.updates.coolweathersite.com` 的查询,其子域名为十六进制编码
- 过滤器:`dns.qry.name contains "coolweathersite"`
- 按顺序拼接十六进制数据块并解码:
```
hex_str = "4354467b646e735f68696465735f696e5f706c61696e5f73696768747d"
print(bytes.fromhex(hex_str).decode())
```
**FLAG:** `Flag{dns_hides_in_plain_sight}`
### FORENSICS-04 — 有毒的数据包 *(350 分)*
**考察知识点:** 基于 TTL 的数据提取
**解题步骤:**
- 在 Wireshark 中打开 `poison_packet.pcap` → 过滤器:`ip.src == 172.16.0.99 && icmp`
- 注意来自连续 ICMP 数据包的异常 TTL 值
- 将 TTL 值转换为 ASCII:
```
ttls = [70,108,97,103,123,116,116,108,95,51,120,102,
49,108,116,114,52,116,49,48,110,125]
print(''.join(chr(t) for t in ttls))
```
**FLAG:** `Flag{ttl_3xf1ltr4t10n}`
## 🖼️ 隐写术
### STEGO-01 — 音频频谱图 *(入门)*
**考察知识点:** 频谱图分析
- 将 `solvemewsh.wav` 上传到频谱图分析器
- Flag 在频谱中以视觉形式编码
**FLAG:** `Flag{stenographycongrats!}`
### STEGO-02 — 隐藏的文本文件 *(中级)*
**考察知识点:** 零宽字符隐写术
**解题步骤:**
```
with open('hollow_archive.txt', 'r', encoding='utf-8') as f:
content = f.read()
zw_map = {'\u200b': '0', '\u200c': '1'}
bits = ''.join(zw_map[c] for c in content if c in zw_map)
chars = [chr(int(bits[i:i+8], 2)) for i in range(0, len(bits), 8)]
print(''.join(chars))
```
**FLAG:** `Flag{Excecutillize}`
### STEGO-03 — 嵌套的 Zip 压缩包 *(高级)*
**考察知识点:** 受密码保护的 Zip 破解
**解题步骤:**
```
fcrackzip -u -D -p wordlist.txt challenge.zip
# 外部密码:dragon
unzip -P dragon challenge.zip
unzip -P nestedflag2024 inner.zip
cat flag.txt
```
**FLAG:** `Flag{double_zip_double_trouble}`
### STEGO-04 — 堆叠的秘密 *(200 分)*
**考察知识点:** LSB 隐写术
**解题步骤:**
```
zsteg stacked_secrets.png
```
或者使用 Python 通过 PIL 手动从像素数据中提取最低有效位。
**FLAG:** `Flag{lsb_st3g0_unv31l3d}`
## 🔎 OSINT
### OSINT-01 — 我在哪? *(75 分)*
**考察知识点:** 逆向图片搜索
- 对提供的照片进行反向图片搜索
- 识别出该地标位于 **波斯尼亚和黑塞哥维那的莫斯塔尔(Mostar, Bosnia and Herzegovina)**
**FLAG:** `Flag{Mostar}`
### OSINT-02 — 联系注册人 *(80 分)*
**考察知识点:** WHOIS 查询
- 在 [whois.domaintools.com](https://whois.domaintools.com) 上查询 `Ebf.edu.mx`
- 在 WHOIS 记录中找到注册人的姓名
**FLAG:** `Flag{HectorMedinaPalma}`
### OSINT-03 — 像素不会说谎 *(150 分)*
**考察知识点:** 图像元数据 / EXIF 分析
```
exiftool challenge.jpg
```
`Image Description` 字段包含 flag。GPS 坐标 (25°N, 55°E) 也确认了位于迪拜。
**FLAG:** `Flag{25N_55E_burjkhalifa_2019}`
### OSINT-04 — 跟随招聘 *(150 分)*
**考察知识点:** 电话键盘密码
- 一则招聘信息列出了招聘热线:`+971-2255387`
- 将数字映射到电话键盘字母:`2255387` → `CALLUS`
FLAG:** `Flag{callus}`
### OSINT-05 — 重新排序 *(180 分)*
**考察知识点:** 供应链 / 制造商 OSINT
- 邮件中的关键规格:SODIMM, DDR4, 3200MHz, Industrial,系列前缀 KT,深圳坪山区
- 搜索指向 **Kimtigo (Shenzhen TIGO Semiconductor)**
- 访问他们的工业内存产品页面 → `KT-B900 SODIMM DDR4 3200MHz`
**FLAG:** `Flag{KT-B900-DDR4-3200}`
## 🎲 杂项
### MISC-01 — ASCII 艺术 *(50 分)*
- 打开文本文件 —— 读取大块的 ASCII 字母
- 它们拼写出:`ASCIIMASTER`
**FLAG:** `Flag{asciimaster}`
### MISC-02 — 摩斯密码 *(50 分)*
**已知:** `-- --- .-. ... . -.-. --- -.. . ..--- ----- ..--- -....`
- 使用 [morsecode.world](https://morsecode.world) 解码 → `MORSECODE2026`
**FLAG:** `Flag{morsecode2026}`
### MISC-03 — 二进制低语 *(150 分)*
- 将二进制分组粘贴到 CyberChef → "From Binary"
**FLAG:** `Flag{b1n4ry_wh1sp3r}`
### MISC-04 — 谜语 *(150 分)*
*"我没有嘴却能说话,没有耳朵却能听见。我没有身体,但随风而来。"*
答案:**echo**
**FLAG:** `Flag{echo}`
### MISC-05 — 读取比特 *(300 分)*
**考察知识点:** Magic Bytes / 文件类型识别
```
file mystery_track.mp3
# Output: PNG 图像数据, 500 x 200, 8-bit/color RGB
mv mystery_track.mp3 mystery_track.png
```
打开重命名后的图像 —— flag 会以文本形式显示。
**FLAG:** `Flag{m4g1c_byt3s_m4tt3r}`
### MISC-06 — 暴露的 Git *(200 分)*
**考察知识点:** Git 历史取证
```
unzip quantbit-portal.zip && cd quantbit-portal
git log --oneline
git show 41ea212
```
原始的 `src/auth.py` 在被“修复”之前包含一个硬编码的机密。
**FLAG:** `Flag{g1t_h1st0ry_n3v3r_l13s}`
## 🛠️ 挑战中使用的工具
| 工具 | 用途 |
|---|---|
| CyberChef | Base64、ROT13、二进制、十六进制解码 |
| Burp Suite | HTTP 拦截、参数篡改 |
| Gobuster | 目录枚举 |
| ExifTool | 图像元数据提取 |
| Wireshark | 数据包捕获分析 |
| Ghidra | 二进制逆向工程 |
| radare2 | 反汇编与分析 |
| Hashcat | 密码哈希破解 |
| zsteg | LSB 隐写术检测 |
| fcrackzip | ZIP 密码破解 |
| jadx | Java 反编译 |
| Scapy | 数据包操作与分析 |
## 📋 活动详情
**WSH'26 —— 威斯敏斯特学校 Hackathon**
*构建。黑客。突破。学习。*
校内 CTF 与 Hackathon —— 迪拜威斯敏斯特学校,2026 年
**挑战总数:** 涵盖 7 个类别的 30 多项挑战
**基础设施:** CTFd 自托管在 Google Cloud Platform 上 → [部署仓库](https://github.com/kaid0x/CTFd-deployment-on-GCP-with-Docker)
**Web 挑战:** 定制的 Flask 应用 → [挑战仓库](https://github.com/kaid0x/wsh26-web-challenges)
## ⚠️ 免责声明
这些题解是在活动结束后出于教育目的发布的。所有挑战文件和易受攻击的应用程序都部署在一个隔离的、受控的环境中。
标签:Web安全, Writeup, 云资产清单, 取证, 域环境安全, 密码学, 手动系统调用, 网络安全, 蓝队分析, 逆向工具, 逆向工程, 隐私保护