HITCON CTF 2022 Writeup

この大会は2022/11/25 23:00(JST)~2022/11/27 23:00(JST)に開催されました。
今回もチームで参戦。結果は251点で430チーム中129位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Misc)

Twitterで#HITCONCTF2022のハッシュタグを含むツイートをした後、Dosicordの#welcomeチャネルで、緑色のボタンを押し、ツイートのURLを指定したら、フラグが表示された。

hitcon{we filled twitter with more spam tweets}

BabySSS (Crypto)

暗号化処理の概要は以下の通り。

・DEGREE = 128
・SHARES_FOR_YOU = 8
・poly: 129個の64ビットランダム整数の配列
・shares = []
・8回、以下繰り返し
 ・x: 16ビットランダム整数
 ・y: poly[0] + poly[1] * x + ... + poly[128] * x**128
 ・sharesにx, yを追加
・shares出力
・secret = poly[0] + poly[1] * 0x48763 + ... + poly[128] * 0x48763**128
・key = sha256(str(secret).encode()).digest()[:16]
・フラグをAES-CTRモードで暗号化し、出力
・暗号化に使ったnonceを出力

8回の各値について、以下のようになる。

(poly[0] + poly[1] * x + ... + poly[128] * x**128) % x = poly[0] % x

この情報からCRTでpoly[0]を求める。
次に各値からpoly[0]を引き、xで割った値を考える。

(poly[1] + ... + poly[128] * x**127) % x = poly[1] % x

先ほどと同様にしてpoly[1]を求める。これを繰り返すことによって、poly全体の値を求める。この値からAES暗号の鍵が生成できるので、復号すればよい。

#!/usr/bin/env python3
from sympy.ntheory.modular import crt
from Crypto.Cipher import AES
from hashlib import sha256

def polyeval(poly, x):
    return sum([a * x**i for i, a in enumerate(poly)])

DEGREE = 128
SHARES_FOR_YOU = 8

with open('output.txt', 'r') as f:
    params = f.read().splitlines()

shares = eval(params[0])
enc_flag = eval(params[1])
nonce = eval(params[2])

poly = []
for i in range(DEGREE + 1):
    ps = []
    ms = []
    for j in range(SHARES_FOR_YOU):
        x = shares[j][0]
        y = shares[j][1]
        ps.append(x)
        for k in range(i):
            y -= poly[k] * x ** k
        ms.append((y // (x ** i)) % x)
    m, _ = crt(ps, ms)
    poly.append(m)

secret = polyeval(poly, 0x48763)
key = sha256(str(secret).encode()).digest()[:16]
cipher = AES.new(key, AES.MODE_CTR, nonce=nonce)
flag = cipher.decrypt(enc_flag).decode()
print(flag)
hitcon{doing_SSS_in_integers_is_not_good_:(}