くれなゐの雑記

例を上げて 自分で手を動かして学習できる入門記事を多めに書いています

SECCON CTF 2021 の作問をさせていただきました

2019年からCTFを初めて、2021年、とうとう作問側に回ることになりました。
始めた当初はSECCONで決勝に行くことを目標にしていて、今では作問側に回る。
なんか感慨深いですね

普段一応動画の教材用に作問していますが、こういったコンテストでは初めて作問するのでドキドキでしたが、無事に終わってよかったです。
教育用の問題ばかりを作っているので難しい問題を作ることができなかった点で少し後悔しています。
次は 1solved 以上で最小の問題を作れるようになりたいですね。

作問でレビューをしてくださった皆様、先に問題を解かせてくださった皆様、インフラや運営などをしてくださった皆様、チャレンジしてくださったみなさまのおかげで無事に終了できたと思っています。本当にありがとうございました。

ここからは個別の作問の裏話をしていこうと思います。

簡易的なwriteupはこちらになるので、writeupをお求めの方はこちらを。
動画は現在鋭意作成中です。

zenn.dev

pppp

これは Xornet さんの作った CCC があまりにもwarmupではなかったため、その場で思いついた問題をいい感じにしたものです。
RSAっぽく計算できる行列を頑張って構築しようと考えたところ、「固有ベクトル有理数になるので、固有値有理数だったら行けるだろ。」という思いつきを椅子に座って回転していると思いつきました。固有値有理数にするためには上三角行列にするのが手っ取り早く、あとは複数要素同時にRSAするならGCDとか入れておけばきれいにまとまるなと思い、pを混ぜ込みました。

GCDでpを漏洩し、その後GCDでフラグを取得するという二連GCDが個人的に好きなポイントです。

予想に反してみんな直感に身を任せてd乗してくれませんでした。実際証明は思いつきにくいので、みんな式変形して解いてて偉いなぁという気持ちになりました。

oOoOoO

これは実はもともとは case insensitive のサブセットの問題でした。case insensitiveは問題の特性上大文字にしなければならなく、大文字小文字を当てるためになにかいい方法はないかと考えたところ、bytes_to_long()って実質 256^i で超増加列になるので実質ナップサック暗号じゃんという気づきを得たので作問に至りました。

bytes_to_long を mod したものは 部分和問題にならないので頭を抱えていたところ、高々文字数分総当りしたら合計値に戻せることを思いついたので、そのまま問題にしました。

ただcase insensitiveで要求される知識セットとoOoOoOで要求される知識セットがあまりにもかけ離れすぎていて、解いてて辛いだろうなと思ったので分離しました。

cerberus

なんかPadding Oracle Attackの問題作りたいなぁと思いWikipediaの図をじっと睨んでいるとivがそのまま最後のブロックに反映されて複数回同じブロックを入れると相殺することが見えたので作問しました。特に思い入れはないです

case insensitive

ßを大文字にするとSSになるという驚きの性質をしり(これに書いてました ->
O'Reilly Japan - プログラミングRust
)、その後色々調べているとffiも大文字にすると大増殖をすることをしり、bcryptかPOODLEあたりで作問しようと思っていました。ちなみに皆さんも魔力回復等に使用されるであろう Æther の Æ は小文字も大文字もあるので1文字のままです。対応している大文字や小文字がない場合特殊な処理としてこのような挙動になります。これはutf-8のしようというよりは文字そのものの仕様の側面が強いですね。

bcryptが72文字制限なのは72bytesのものとxorするフェイズがあるのですがそこでそれ以上足りなくなっちゃうからですね、これは内部で使われているblowfishの仕様です。