Hawk Ii

0xFun CTFby smothy

Hawk_II - Crypto

Points: 680 | Flag: 0xfun{tOO_LLL_256_B_kkkkKZ_t4e_f14g_F14g} | Solved by: Smothy @ 0xN1umb

bruh moment

what we got

three files: Hawk_II.sage, hawk.sage, and output.txt. challenge description says something about hawks feathers and identifying which hawk. sounds like a lattice crypto challenge

hawk.sage implements the full HAWK signature scheme - a post-quantum lattice-based signature scheme using cyclotomic fields of degree 256. pretty serious crypto

the "solve"

so here's Hawk_II.sage (the important bits):

python
# generate HAWK keypair
Sig = SignatureScheme(n, sigma_kg, sigma_sig, sigma_ver)
sk, pk = Sig.KGen()

# encrypt flag with AES using sk as key material
key = sha256(str(sk).encode()).digest()
cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
enc = cipher.encrypt(pad(FLAG, 16))

# output pk, partial leaks of sk components...
print(f"{pk = }")

# and then...
print("sk = ",sk)  # <--- BRUH

you see it? line 61. print("sk = ",sk). the FULL secret key. just printed. right there in output.txt

the challenge sets up this whole elaborate partial leak system - leaking half the coefficients of sk0 at random indices and the complementary half of sk1. you're supposed to use LLL/BKZ lattice reduction to recover the full key from partial information

but then it just... prints the whole thing anyway

actual solve

python
with open("output.txt") as f:
    content = f.read()

# extract the sk tuple string from output
sk_start = content.find("sk =  ")
line_start = content.find("(", sk_start)
# find matching closing paren
depth = 0
for i in range(line_start, len(content)):
    if content[i] == '(': depth += 1
    elif content[i] == ')':
        depth -= 1
        if depth == 0:
            pos = i
            break

sk_str = content[line_start:pos+1]

# decrypt
key = sha256(sk_str.encode()).digest()
cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
flag = unpad(cipher.decrypt(enc), 16)
# => 0xfun{tOO_LLL_256_B_kkkkKZ_t4e_f14g_F14g}

no sage needed. no lattice reduction. no LLL. no BKZ. just string parsing and AES decrypt

flag

0xfun{tOO_LLL_256_B_kkkkKZ_t4e_f14g_F14g}

the flag literally says "too LLL 256 BKZ the flag" - trolling about all the lattice attacks you didn't need to do. i spent more time installing sage (which failed) than actually solving this. sometimes the real crypto attack is reading the source code


smothy out ✌️