CPCTFに参加しました。楽しかったですね!
新入生のみなさま、入学おめでとうございます。新しい生活が始まりましたね。
traPの先輩方、楽しい問題をたくさん用意してくださりありがとうございました。ヒントを含めて、とっつきやすい工夫が素晴らしかったです。楽しい週末が過ごせました。
祝辞がわりに、Writeupを書いていきます。
暗号もの(Crypto)
Dualcast (Crypto Lv.1)
文字列とバイト列と整数の変換。
Very Exciting (Crypto Lv.2)
Stream暗号において、鍵(Key)とイニシャルベクター(Initial Vector, IV)を同じにしたら(使いまわしたら)、KeyStreamが同じになっちゃうよ、という問題。
IVを指定できるので、flagを暗号化したIVを指定して、favoriteとその暗号文enc_favoriteを得る。
そしたら、
keystream = favorite ^ enc_favorite
となるので、
flag = enc_flag ^ favorite ^ enc_favorite
で求められる。^はxor演算子。
pythonのもっとも美しい文法を使うと次のように書ける。b_xxはバイト列。
b_flag=bytes([x ^ y ^ z for x, y, z in zip (b_favorite, b_enc_favorite, b_enc_flag)])
この文法、Schemeのmapみたいで好き。
なお、Pythonのzipは可変長引数を受け取れる(schemeのmapと同じ)。
ところで、この問題のkeystreamを作るための疑似乱数生成器があまりに立派だったので、内部状態を予想する問題かと思って、だいぶ遠回りをしてしまった。
SBOXも自分で定義しているFeistel暗号だから、みなさまもぜひ鑑賞してほしい。
1,0,7 (Crypto Lv.3)
RSAでNが因数分解できる。
pとqがわかるときのRSA復号は、通常通り。昔書いたスクリプトがあったので、それを使用して暗号文を復号した。
Anomaly 2 (Crypto Lv.3)
ヒントの通り、m(=flag)を共通の因数としてもつ2つの整数が手に入るから、ユークリッドの互除法で最大公約数gcdを求める。最大公約数gcdは「flagそのもの」か、「flagの倍数」となるからである。
最大公約数はflagの形式ではなかった。そこで、最大公約数を見ると最後の桁(1の位)が0である。すなわち2と5で割れる。
試しにgcdを2で割ってみたら、flagが現れた。
Janken Master (Crypto Lv.3)
こちらも、疑似乱数生成器。初期ステートが0000...00にできれば、ずーっとステートが0000..00で続くことを利用する。
ヒントを参考に「xoroshiro128 period」とGoogleで検索すると、
全てが0の状態を除いた、128ビットで表現可能なほぼ全ての状態を網羅する「フル周期」ジェネレータです。
との検索結果(AIモード)を得る。
これから、内部ステートを0000..00にすればよさそうと思いながら、提供されたコードを見ると、確かに行けそうである。
ncで入力したseedは、0x1234567890abcdef1234567890abcdefとxorをとってから、Xoroshiro128Plusに入力されてそのまま内部ステートになるので、ncで0x1234567890abcdef0x1234567890abcdef(を10進表記にした整数)を入力すればよい。
Bitwise Scrumble (Crypto Lv.4)
flagを3分割して、bit単位でkeyとごにょごにょする。「ごにょごにょ」の部分は丁寧に見ると、3分割すべての部分でxorであることがわかる。
なので、文字列(16進数の場合と、大きい10進数の整数の場合がある)とバイト列と整数を混同しないように注意して、与えられているencrypt(text)の逆関数を作ればよい。
暗号以外
Hidden (Reversing Lv.1)
stringコマンドを使うまでもなく、lessで検索をかけても見つかった。
L0v3 PDF (Forensics Lv.1)
lessで検索をかけたら見つかった。
mirage (Web Lv. 1)
Firefoxで開いて、「ソースを表示」して検索をかけたら見つかった。
見た目と選択される文字列が違うって面白いですよね。
ssh (Shell Lv.1)
sshするのみ。リクエストに応じてインスタンスを立ち上げる環境を用意していてすごい。
Flag in Flags (Forensics Lv.2)
exiftoolとlessで見たけど、付随情報にはなさそう。
旗の絵の中に、人間では区別できない違う色で文字が書いてあると予想した。
それならばGIMPで加工して見えるようにしていこう。
なので、「GIMP 特定の色を変える」で検索して、色交換の方法にたどり着いた。
GIMPで出題された画像を開いて、旗の色をpick colorして、色交換(Color Exchange)で白に変えていったら、文字が現れた。
ssh2 (Shell Lv.2)
sortやuniqコマンドが使えた。
環境
Kali Linux 2026.1
Python 3.x
結び
traPのみなさま、あらためまして、楽しい時間をありがとうございました。
みなさまが楽しい学生生活を送れるよう、心から願っております!