みなさん初めまして、traPで3DCGとCTFをやっている22Bのkaitoyamaです。
去る10/1 午前1:00〜10/3 午前1:00で開催されていたSekaiCTF 2022に参加しました。結果は25位でした。自分が解けた問題に対してそのwriteupというのを書きます。
目次
- [misc] ConsolePort
- [PPC] Let's Play Osu!Mania
- [misc] Matryoshka
- [Forensics] Broken Converter, flag MONO
- [crypt] FaILProof
writeup
[misc]Console Port
渡されたコマンドをターミナルに打つとあら不思議、ターミナルでKEEP TALKING and NOBODY EXPLODESが遊べます。という問題。マニュアル片手に1人で爆弾解除ができればフラグがもらえました。
オープンしてすぐに取り掛かった一問で、自分の環境ではKeypadsの文字が一部・
になってしまっていたので、運要素が入り難易度が上がっていました。
[PPC]Let’s Play Osu!Mania
Osu!Maniaの譜面を模した標準入力が与えられて、ホールドノードをうまく処理して、いくつのノーツがあるかを求めるというものでした。ホールドノードを最後尾以外全部消してしまえば、すぐに解けました。
ここまでは広義の10/1に解きました。
[misc]Matryoshka
最初見た時には、カラフルな背景とその上のカラフルな絵文字😀の色を読み取る必要があったのですが、その後で、背景を読めばいいようになった方の手がかりが与えられたので、人力で全てANSIの色コードに起こしました。
これで、data.txtを復元して見るとurlだったので、アクセスしてみる。
すると、細かい横線のノイズの入ったQRが、ところが、これは「Never Gonna Give You Up」という曲のYouTubeへのリンク。
ここで詰まっていたところ、運営からヒントが出ました。
「“Never reinvent your own wheel”, people say. But Apple insisted on thinking differently when parsing PNGs.」
どうやら、AppleがやっていたPNGのデコーディング方法を使うといいらしい。そこで、手元のmac bookで開いてみる、しかし、何も変わらない。なぜ!?
実はAppleがパッチを当ててしまったらしい。そこで色々検索しているとhttps://fotoforensics.com/
でデコーディングを試せた。
ここで終わらないのがLevel4。そこで出てくるQRを読むとshcが出てくる。
検索するとこれはコロナワクチンの接種歴証明のフォーマットらしく、簡単にデコードできた。
すると"また"、URL。そこには、ノイズばかりのステレオファイルが。そこで、お手元のizotopeのRXに突っ込んでノイズを減らすと微かに女性の声が。このファイルにはちゃんと意味のあることが収録されているということで、モノラル再生にしてみると、あら不思議、はっきりとフォネティックコードが。英語の聞き取りが不安なので、最近話題になったwhisperに入れると、やっとフラグ。
とにかく、これでもかというほどいろんな仕掛けがあって途中で心が折れそうになりましたが、解き終わった時の達成感はすごかったです。これが個人的には一番楽しかった問題でした。
[Forensics]Broken Converter,flag MONO
この二問は渡されたxpsファイルを色々みる問題。
とりあえずxpsをみるとお馴染み「lorem ipsum」が。しかし、文を選んでコピペするとなぜか違う文字列が出てくる。そこで、フォントを確認したくなったので、odttfをttfにするツールをネットで探して使ってttfにしました。
ところが、そこから、やることが全く分からず。
しばらくして、なんとなく、フォント管理ソフトでttfのunicode表をみると、なんとそこに、フラグがあるではありませんか!ということで、unicodeの英数字あたりを入れ替えてフラグが作られていました。(Broken Converter)
しかし、ここから、さらにもう一つフラグを見つけなければならないということ。色々他のCTFのwriteupをみるとどうやら、フォントの機能を使ってフラグを隠した例があるとのこと。
そこでhttps://fontdrop.info/
で色々やっていると、OpenType featuresをいじるとフォントのなまえ「flag MONO」がフラグのように変化している!
かくして解くことができました。
これは、本当にフォントファイルの奥深さを学んだ問題でした。
[Crypto]FaILProof
渡されたpythonファイルを見て、解読するとほとんどわかったのですが、happinessという関数だけ、実験からpopcountと同じでは?と思ったのですがネットで探した他の関数と結果が合わず。先輩に聞くとやはりそうとのことらしいので、ネットで探したpopcountが間違っていたと判断し、それをもとに連立方程式を立てて、"線形代数"を使って解きました。
具体的には...
暗号化の手順
- 公開鍵を作る
- FLAGを64文字ずつに分けて数値にする(ブロックと呼ぶ)
- それぞれのブロックですべての公開鍵に対して論理積を取ってから以下の処理をした値を出力する。
def happiness(x: int) -> int:
return x - sum((x >> i) for i in range(1, x.bit_length()))
公開鍵一つ分だと桁数に対して式が足りなかったので、二つ使って解きました。
byteとintの行き来が大変だったのと、もう少しちゃんと考察すべきだったなぁと思います。行列のありがたさも感じました。
全体を通しての感想
終わってから[Crypto] Secure Image Encryptionの元論文を確認すると、後一押しだったことが判明。押し切りたかったところです。
初めてちゃんと貢献できたと思えるCTFなので嬉しかったです。
全体的にサイトのデザインやフラグの文字列がプロセカに寄せてあって、(ジャンル名がバンド名みたいなデザインだった!!)解いていてテンションが上がりました。
次も頑張ります。