1025 字
5 分钟
2026 御网杯 线上 ECB Pattern Leakage Writeup

ECB Pattern Leakage#

Summary#

一道 AES-ECB 弱密钥爆破题目。附件名 otp_07.zip 是干扰项,真实加密方式为 AES-ECB(电子密码本模式)。通过构建”常见单词+分隔符+特殊字符”模式的 16 字节密钥字典,逐条尝试 AES-ECB 解密,最终爆出密钥 VERY_SECRET_KEY! 并获得 flag。

Solution#

1. 题目分析#

题目名 “ECB Pattern Leakage” 直接提示了加密模式:

  • ECB = AES-ECB(电子密码本模式),无 IV,加密解密仅依赖 16 字节密钥
  • Pattern Leakage = ECB 的经典弱点:相同明文块产生相同密文块,泄露数据结构

附件 otp_07.zip 解压得到 ciphertext.bin,长度 80 字节 = 5 个 AES 块(80 / 16 = 5),进一步确认是 AES 加密。

密文 hex: 97c266c5b1c929e1ac07ccf592599dd8
39677b7c0a37f1772c158da16cd0e9a4
31324b424c712cbf200443c4ec7fc624
92b016e07838e966cfde3f6f93903698
84163f757a2ab28337aefa7aeb72e087

核心思路:CTF 中常硬编码弱密钥,密钥由「常见英文单词 + 分隔符(_、- 等)+ 特殊字符」组合成恰好 16 字节。需要系统性地生成候选密钥字典并逐一爆破。

2. 字典生成策略#

字典由以下来源合并,共生成约 838 万 个 16 字节候选密钥:

来源一:常见密码词 + 填充补齐

收集约 150 个常见密码关键词(secret, key, password, admin, master, flag, aes 等),包含三种大小写变体(原形 / 全大写 / 首字母大写)。对不足 16 字节的,用 0、!、#、 、*、@、$、1、_ 填充到 16 字节。

来源二:单词组合模式

  • 28 个基础词库:very, secret, key, pass, flag, code, safe, lock, open, hard, soft, test, back, hide, deep, blue, gold, red, hot, big, old, new, raw, aes, ctf, crypto, password, admin, root, master, super
  • 分隔符:_、-、.、+、@、#
  • 双词 / 三词组合 × 大小写变体 × 特殊字符后缀 → 海量 16 字节候选

来源三:数字编号模式

如 key0000 ~ key9999,aes0000 ~ aes9999 等,填充到 16 字节。

来源四:题目特定猜测

根据 otp_07 命名生成针对性候选(OTP_KEY_007!!!、ECB_KEY_007!!!、MASTER_KEY_007! 等)。

3. 爆破脚本#

from Crypto.Cipher import AES
import re
ct = open("otp_07_extracted/ciphertext.bin", "rb").read()
def pkcs7_unpad(data):
pad_len = data[-1]
if 1 <= pad_len <= 16 and data[-pad_len:] == bytes([pad_len]) * pad_len:
return data[:-pad_len]
return data
candidates = set()
# ——— 来源一:常见密码 + 填充 ———
common = [
"very", "VERY", "Very", "secret", "SECRET", "Secret",
"key", "KEY", "Key", "pass", "PASS", "Pass",
"flag", "FLAG", "Flag", "admin", "Admin", "ADMIN",
"master", "MASTER", "Master", "super", "SUPER", "Super",
"aes", "AES", "Aes", "ctf", "CTF", "Ctf",
"crypto", "CRYPTO", "Crypto", "password", "PASSWORD",
"very_secret", "VERY_SECRET", "super_secret", "SUPER_SECRET",
"master_key", "MASTER_KEY", "top_secret", "TOP_SECRET",
]
for pw in common:
wb = pw.encode()
if len(wb) == 16:
candidates.add(wb)
for pad in [b"0", b"!", b"#", b" ", b"*", b"@", b"$", b"1", b"_"]:
candidates.add(wb.ljust(16, pad))
# ——— 来源二:单词组合 ———
base = [
"very", "secret", "key", "pass", "flag", "code", "safe", "lock",
"open", "hard", "soft", "test", "back", "hide", "deep", "blue",
"gold", "red", "hot", "big", "old", "new", "raw", "aes", "ctf",
"crypto", "password", "admin", "root", "master", "super",
]
seps = ["_", "-", ".", "+", "@", "#"]
specials = ["!", "@", "#", "$", "%", "&", "*", "1", "0"]
def variants(w):
return {w, w.upper(), w.capitalize()}
for w1 in base:
for v1 in variants(w1):
for w2 in base:
for v2 in variants(w2):
for sep in seps:
b = v1 + sep + v2
if len(b) > 14:
continue
for w3 in base:
for v3 in variants(w3):
combo = b + sep + v3
if len(combo) > 16:
continue
if len(combo) == 16:
candidates.add(combo.encode())
for s in specials:
full = (combo + s)[:16]
if len(full) == 16:
candidates.add(full.encode())
for s in specials:
full = b.ljust(16, s[-1] if s else "!")
full = full[:16]
if len(full) == 16:
candidates.add(full.encode())
# ——— 来源三:数字编号 ———
for prefix in ["key", "KEY", "Key", "aes", "AES", "Aes"]:
for i in range(10000):
key = f"{prefix}{i:04d}".encode()
candidates.add(key.ljust(16, b"0"))
candidates.add(key.ljust(16, b"!"))
# ——— 爆破 ———
for key in candidates:
try:
cipher = AES.new(key, AES.MODE_ECB)
pt = cipher.decrypt(ct)
text = pt.decode("ascii")
except:
continue
if not any(kw in text for kw in ["CTF", "flag", "FLAG", "Flag"]):
continue
clean = pkcs7_unpad(pt)
print(f"[+] Key: {key!r}")
print(f"[+] Plaintext: {clean.decode()}")
match = re.search(rb"flag\{[^}]+\}", clean)
if match:
print(f"[+] Flag: {match.group().decode()}")
break

4. 运行结果#

[*] 总候选密钥数: 8380467
[+] Key: b'VERY_SECRET_KEY!'
[+] Plaintext: CTF{SECRET_FLAG:flag{dt6g0oomiiiyqb2jtbm93h5dsi07alzp}}END_OF_FLAG
[+] Flag: flag{dt6g0oomiiiyqb2jtbm93h5dsi07alzp}

在第约 120 万个候选时命中,密钥与 otp_02 相同(均为 VERY_SECRET_KEY!),但 flag 不同,说明同一套题用了统一密钥、不同明文。

Flag#

flag{dt6g0oomiiiyqb2jtbm93h5dsi07alzp}

总结#

考点说明
AES-ECB 模式电子密码本,无 IV,解密仅需密钥
弱密钥爆破密钥由常见单词组合成 16 字节,可用字典爆破
文件名干扰otp_07 是误导,实际与 OTP 无关
PKCS#7 填充用于验证解密正确性

关键教训:题目名是最可靠的线索(“ECB Pattern Leakage”),附件名往往是干扰项。CTF 中弱密钥常遵循 WORD_SEP_WORD_SPECIAL 模式,系统性地生成这种字典可覆盖绝大多数情况。

2026 御网杯 线上 ECB Pattern Leakage Writeup
https://nan.sajunan.cn/posts/ecb模式泄露爆破wp/
作者
Inui Sajuna
发布于
2026-07-17
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取