🐕

ångstromCTF 2021 - Follow the Currents

1 min read

問題概要

go with the flow... Source

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

ログインするとコメントできます