深处的神谕只对懂得低语的人开口。每一次错误的祷文,都让她吐露一个字节的秘密。 题目地址:39.105...
تم الإنشاء في: ١٠ مايو ٢٠٢٦
تمت الإجابة باستخدام GPT-5.5 Thinking بواسطة Chat01
تم الإنشاء في: ١٠ مايو ٢٠٢٦
تمت الإجابة باستخدام GPT-5.5 Thinking بواسطة Chat01
深处的神谕只对懂得低语的人开口。每一次错误的祷文,都让她吐露一个字节的秘密。
题目地址:39.105.213.28:12605
我这边连了几次,39.105.213.28:12605 当前都是:
textConnection refused
所以暂时没法直接拿到 banner/密文/flag。题面线索很明显:“神谕 / Oracle”“错误的祷文”“一个字节的秘密”,大概率是 CBC Padding Oracle,也就是通过错误反馈一字节一字节解密密文。
下面给你一份可直接改的脚本。等服务恢复后,先用:
bashnc 39.105.213.28 12605
把 banner 里的密文复制到 TOKEN_HEX,然后跑脚本。
python#!/usr/bin/env python3 import socket import re HOST = "39.105.213.28" PORT = 12605 BLOCK = 16 # 把服务给你的 IV + ciphertext 十六进制字符串填这里 TOKEN_HEX = "填这里" # 根据服务返回改这里: # 只要响应里出现这些关键词,就认为 padding 错误 BAD_MARKERS = [ b"invalid", b"error", b"wrong", b"bad", b"fail", b"incorrect", b"\xe9\x94\x99", # “错”的 UTF-8 片段 ] def query(payload_hex: str) -> bytes: s = socket.create_connection((HOST, PORT), timeout=5) s.settimeout(2) try: # 读初始提示 try: s.recv(4096) except socket.timeout: pass s.sendall(payload_hex.encode() + b"\n") data = b"" while True: try: chunk = s.recv(4096) if not chunk: break data += chunk except socket.timeout: break return data finally: s.close() def oracle(payload: bytes) -> bool: resp = query(payload.hex()) low = resp.lower() for m in BAD_MARKERS: if m in low: return False # 如果没有明显错误提示,默认认为 padding 有效 return True def decrypt_block(prev: bytes, cur: bytes) -> bytes: intermediate = [0] * BLOCK plain = [0] * BLOCK for pos in range(BLOCK - 1, -1, -1): pad = BLOCK - pos prefix = bytearray(prev) for j in range(pos + 1, BLOCK): prefix[j] = intermediate[j] ^ pad found = False for guess in range(256): prefix[pos] = guess forged = bytes(prefix) + cur if oracle(forged): intermediate[pos] = guess ^ pad plain[pos] = intermediate[pos] ^ prev[pos] print(f"[+] byte {pos:02d}: {plain[pos]:02x} {bytes([plain[pos]])!r}") found = True break if not found: raise RuntimeError(f"failed at byte {pos}") return bytes(plain) def unpad(data: bytes) -> bytes: p = data[-1] if 1 <= p <= BLOCK and data.endswith(bytes([p]) * p): return data[:-p] return data def main(): token = bytes.fromhex(TOKEN_HEX.strip()) assert len(token) % BLOCK == 0 blocks = [token[i:i + BLOCK] for i in range(0, len(token), BLOCK)] plaintext = b"" for i in range(1, len(blocks)): print(f"[*] decrypting block {i}/{len(blocks)-1}") plaintext += decrypt_block(blocks[i - 1], blocks[i]) print("\n[+] plaintext:") print(unpad(plaintext)) if __name__ == "__main__": main()
关键点:
IV || ciphertext,脚本可以直接用。IV + ciphertext 拼起来填进 TOKEN_HEX。BAD_MARKERS 要按真实返回改。比如服务返回“祷文错误”“沉默”“padding error”,就把对应字节串或英文关键词加进去。目前卡点不是解法,而是远端端口拒绝连接。服务恢复后,把第一次连接的完整输出贴出来,我可以把脚本改成完全匹配该服务协议的版本。