0x401 - World’sEnd Secure Box
题目信息
附件里有三个文件:
note.txt
securebox.enc
secureboxMain.exe
secureboxMain.exe 用 Detect It Easy 看是 Python 打包程序,体积和结构都比较像 PyInstaller;securebox.enc 只有 48 字节,说明真正的密文很短;note.txt 表面上是一段提示和 ASCII art,末尾还藏了一串不可见字符。
逆向
先用 pyinstxtractor.py 解 PyInstaller 包:
python D:\tools\reverse\pythonre\pyinstxtractor.py secureboxMain.exe
解出来后入口文件是 secureboxMain.pyc,Python 版本是 3.11。pycdc 对 3.11 支持不完整,但主逻辑已经能看出来;不完整的地方用 pycdas 看字节码即可。
关键常量如下:
ZW_0 = "\u200b"
ZW_1 = "\u200c"
ZW_SEP = "\u200d"
这三个字符分别是:
U+200B ZERO WIDTH SPACE
U+200C ZERO WIDTH NON-JOINER
U+200D ZERO WIDTH JOINER
加密逻辑可以还原为:
key = get_random_bytes(32)
iv = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pkcs7_pad(plaintext, AES.block_size))
写 note 的逻辑是:
zw_key = bytes_to_zero_width(key)
zw_iv = bytes_to_zero_width(iv)
zw_combined = zw_key + ZW_SEP + zw_iv
note = LOG_MSG + zw_combined
bytes_to_zero_width 会把每个字节转成 8 位二进制,然后把 0 替换成 \u200b,把 1 替换成 \u200c。也就是说,note.txt 末尾的不可见字符就是 AES key 和 iv,中间用 \u200d 分隔。
解密
直接从 note.txt 里提取这三类零宽字符,按规则转回字节,再用 AES-CBC 解密 securebox.enc。
from pathlib import Path
from Crypto.Cipher import AES
ZW_0 = "\u200b"
ZW_1 = "\u200c"
ZW_SEP = "\u200d"
def zw_to_bytes(s):
bits = "".join("0" if ch == ZW_0 else "1" for ch in s)
return bytes(int(bits[i:i + 8], 2) for i in range(0, len(bits), 8))
note = Path("note.txt").read_text(encoding="utf-8")
enc = Path("securebox.enc").read_bytes()
payload = "".join(ch for ch in note if ch in (ZW_0, ZW_1, ZW_SEP))
key_part, iv_part = payload.split(ZW_SEP)
key = zw_to_bytes(key_part)
iv = zw_to_bytes(iv_part)
pt = AES.new(key, AES.MODE_CBC, iv).decrypt(enc)
print(pt[:-pt[-1]].decode())
提取出来的参数为:
key = a17dee8e1c4cbea3df66fb3425e7e8b5e6b147a1e160414cf55ce71e08e24b19
iv = fa16800cd3c1226e319a4b19bdd81b5f
运行结果:
flag{Secure_Storage_or_Secure_box_or_MYSECRET?}