flag = open('flag.txt').read().strip() print('flag: ', mkaes([0]+dh).encrypt(flag.encode()).hex())
for _ inrange(2048): c = list(struct.unpack(f'<{n}H', bytes.fromhex(input()))) r = list(map('01'.index, input())) iflen(r) != n orsum(r) < n//2: exit('!!!')
再來關鍵是 extract 被定義為
lambda r,d: [2*t//q for u,t in zip(r,d) if u],所以
r 的意思其實是告訴它要取 d 解密出來的哪些
bits。所以它輸出的 bits 長度其實就只有 sum(r)
而已,所以可操作空間很大。
題目有要求說 sum(r) >= 128,所以透過取 r
為 [1]*128+[1,0,...], [1]*128+[0,1,...]
這樣下去的話可以發現輸出的 ciphertext 只有兩個可能,因此就能知道
[2*t//q for t in d]
的後半是多少,不過這邊會有兩種可能要爆。然後再微調一下這個方法拿到前半的
bits,因此會有四個 [2*t//q for t in d] 的可能。
from pwn import process, remote from Crypto.Cipher import AES import struct, hashlib
n = 256 q = 11777 w = 8
ppoly = lambda g: struct.pack(f"<{n}H", *g).hex() pbits = lambda g: "".join(str(int(v)) for v in g) hbits = lambda g: hashlib.sha256(pbits(g).encode()).digest() mkaes = lambda bits: AES.new(hbits(bits), AES.MODE_CTR, nonce=b"")
# io = process(["python", "vuln.py"]) io = remote("116.203.41.47", 4421) io.recvuntil(b"ct[0]: ") c = list(struct.unpack(f"<{n}H", bytes.fromhex(io.recvlineS().strip()))) io.recvuntil(b"ct[1]: ") r = list(map(int, io.recvlineS().strip())) io.recvuntil(b"flag: ") flag = bytes.fromhex(io.recvlineS().strip())
defrecover_first_half(): res = [] r = [1] * 128 for i inrange(128): t = [0] * 128 t[i] = 1 rr = t + r io.sendline(ppoly(c).encode()) io.sendline(pbits(rr).encode()) for _ inrange(128): res.append(bytes.fromhex(io.recvlineS().strip())) assertlen(set(res)) == 2 for one inset(res): yield [int(x == one) for x in res]
defrecover_second_half(): res = [] r = [1] * 128 for i inrange(128): t = [0] * 128 t[i] = 1 rr = r + t io.sendline(ppoly(c).encode()) io.sendline(pbits(rr).encode()) for _ inrange(128): res.append(bytes.fromhex(io.recvlineS().strip())) assertlen(set(res)) == 2 for one inset(res): yield [int(x == one) for x in res]
for first in recover_first_half(): for second in recover_second_half(): full_bits = first + second dh = [x for x, y inzip(full_bits, r) if y] print(mkaes([0] + dh).decrypt(flag)) # hxp{e4zy_p34zY_p34nuT_Bu7t3r}