🐕
ångstromCTF 2021 - Follow the Currents
問題概要
import os
import zlib
def keystream():
key = os.urandom(2)
index = 0
while 1:
index+=1
if index >= len(key):
key += zlib.crc32(key).to_bytes(4,'big')
yield key[index]
ciphertext = []
with open("plain","rb") as f:
plain = f.read()
assert b"actf{" in plain
k = keystream()
for i in plain:
ciphertext.append(i ^ next(k))
with open("enc","wb") as g:
g.write(bytes(ciphertext))
zlib.crc32
というやや聞きなれないものを利用しているようです。
解説
問題点はkeystream
で利用されているkey
の初期化が2byteしかないという点です。これは全探索が容易な数値です。
また、暗号化の作業でXORを用いているので、一番最初の鍵さえ分かれば復元が可能です。ということで鍵を全探索してそれぞれの場合で復号が出来るか試します。
solve.py
import zlib
def keystream(key):
index = 0
while 1:
index += 1
if index >= len(key):
key += zlib.crc32(key).to_bytes(4, 'big')
yield key[index]
f = open("enc", "rb")
cipher = f.read()
for key in range(256 ** 2):
keys = key.to_bytes(2, "big")
k = keystream(keys)
plain = []
for i in cipher:
plain.append((i ^ next(k)).to_bytes(1, "big"))
plain = b"".join(plain)
if b"actf{" in plain:
print(plain)
Discussion