MMA CTF 2015
http://uecmma.github.io/mmactf/ja/
なんかとても面白かった。21位。あまり気力の無い季節なので、 Pwn を避けて慣れないジャンルを解く感じで。ただスプラトゥーンを始めてしまったため、最後の20時間は問題読むくらいしかしてなくて28時間コンテストでした。
マジメに参加してない上に簡単な問題しか解いてないですけど、問題セットは僕にはすごく楽しかったです。色んなジャンルで、ちょっとこじゃれた感じというか。運営もほとんどヘンなトラブル無かったように思いますし。
成果物: https://github.com/shinh/mma-ctf-2015
解いた問題
Pattern Lock
https://github.com/shinh/mma-ctf-2015/blob/master/pat.cc
https://github.com/shinh/mma-ctf-2015/blob/master/pat3.cc
Android のパターンでロックを解除するやつ、何通りあるか、て問題。2問目は4x4で最長のパターンの長さを求めよ、てやつ。2問目はメモ化必要だった。割と ICPC スタイル。
Smart Cipher System
https://github.com/shinh/mma-ctf-2015/blob/master/c2.cc
https://github.com/shinh/mma-ctf-2015/blob/master/c4.cc
https://github.com/shinh/mma-ctf-2015/blob/master/c5.cc
いくつかの古典暗号。3つ目はブルートフォースで、4つ目は手をつけなかった。
Login as admin!
SQL injection
Splitted
https://github.com/shinh/mma-ctf-2015/blob/master/splitted.rb
pcap 内の Partial Content で帰った HTTP リクエストを適当につなげるだけ。
How to use?
https://github.com/shinh/mma-ctf-2015/blob/master/howtouse.rb
DLL らしいが win バイナリ作るとかめんどくさいんで、 objdump 見て答えぽいところのデータをつないでるだけ。
RPS
https://github.com/shinh/mma-ctf-2015/blob/master/rps.rb
じゃんけんに50回勝てという問題。名前を最初に入れるのでバッファオーバーフローさせてエンディングにいきなり飛ばすゲー。
This program cannot be run in DOS mode
https://github.com/shinh/mma-ctf-2015/blob/master/cannotberun.rb
MZ ヘッダから PE ヘッダが参照されてないのでオフセットを書くだけ。笑っちゃうくらい短い解答やな。
Signer and Verifier
https://github.com/shinh/mma-ctf-2015/blob/master/sign.rb
本来 sign させたいメッセージを少し加工したものに sign してもらうと、そこから元のメッセージを sign できるという話。
Encrypted
見てない
Impossible?
見てない
Simple Hash
解けなかった
文字列に対して、
hash = 0; for (ch in str) { hash *= 577; hash += ch; hash %= <50bitくらいのでかい数字>
で計算されるハッシュで、狙った数字を出せってもの。
時間内に解けなかったのだけど、 50bit なので最後の方の文字列で調整できる部分以外を bruteforce すればたぶん 30bit もやれば良い気がするので解ける気がする。
これ一般的に解くことできるのかなぁ…というのがわからない。
Uploader
script タグがあれば <? とか php とか使わずに PHP が実行させられる。
パス知ってれば他のチームが upload したファイルが見えるので、適当に flag とかそういうファイル名のファイルを見てみたら、 MMA{uploader_is_not_safe} みたいなそれっぽいニセフラグをアップロードしてたチームがあったぽくて笑った。
Login As Admin!(2)
見当もつかなかった。
Mortal Magi Agents
遊んでみたけど閃きの神様は降ってこなかった。
Motto Mijikai Address
ちょっと遊んでみたけどわからなかった。てかほとんど誰も解いてないじゃないか。
regrettable ecc
見てない
LCGsign
見てない
stream...
ストリーミング動画再生してた pcap 的なものから動画取り出せと。まあやりゃできるんだろうけど、と思いつつぱっと見て使えそうなヘッダとかがわからなかったのでやらなかった。
spell
ちょっと遊んでみてクラッシュしなかったので、まあ良いかと思った。
d3flate
解けなかった。 zlib で圧縮した結果がうまいこと shell 奪える攻撃になるようにしろってこと?
Nagoya Castle
https://github.com/shinh/mma-ctf-2015/blob/master/nagoya.cc
点数的にとりあえず下位1bitでーと思ったらあってた。
Miyako
点数的にあきらめた
QR code recovery challenge
一応 QR code 画像をテキストに落とすくらいはやって、 strong-qr-decoder でデコードできなかったぽいので放置した。 SECCON で QR code 嫌いになったんだ。。
Money Game
https://github.com/shinh/mma-ctf-2015/blob/master/money.rb
1問目は株の売買で1万ドルを10万ドルに増やせというマネーゲーム。うーんこれ最適解計算できるのかな?とか思いつつ、とりあえず買ってすぐ売るというのを貪欲にやるのを書いたら、イマイチ足りない。任意の期間で買って休んで売る、てのを一番トクするやつから順に貪欲に取っていったら、10回に1回くらいは成功するようになったので良いとした。
2問目は1問目解くと名前聞かれて、 printf format を喰わせるとあら大変という定番のやつ。
GOT 書き換えて、ただ実行と書き込み可能な領域は無いから stack を大幅に pop してくれるところに飛んでから、 ROP 。なんだか結構手こずった。
第一段階の成功率があまり高くないのと bruteforce 好みでないから、 stack のアドレス決め打ちとかはせず、メインバイナリの中にあるものだけでやろうとしたからかなと思った。あと1回で行けそうだから、1回でやったけど、結構長くなってしまって色々調整手こずったのもあるので、2回に分けた方が良かった気がする。
手口的には fclose の飛び先を stack を 11 回分 pop してくれる地点にして、 fopen を呼ぶ call 命令の地点に飛び、引数は flag2 になるように stack が調整されてて、 2 回目の fclose でまた 11 回 pop してその後の飛び先を fflush にして完了。
この問題、なぜか最初に解けた。 Pwn 強い人が前哨戦解けなかったか解かなかったのでは。。
Alicegame
やってない
Bow tickets
やってない
Digital Circuit
https://github.com/shinh/mma-ctf-2015/blob/master/dc.rb
普段やらないジャンルーということでハードウェア。 Verilog のコードから変換されたアセンブリみたいなもの(素人すぎてこれをなんというのかすら知らない)に適切な入力を与えて Correct!!! と出させましょう、みたいなやつ。
素人すぎてよくわからないので、適当に途中結果を $display 足して見てみたりして、その後 gtkwave というのがあるなーと色々値を見てみたりする。
でーめんどくさくなって、どうもよくわからんが c1 てのと c2 てのと c4 てのが全部 0 になったらよくて、 256bit の入力のうち、 c1 は 64bit を使い c2 も 64bit 、 c4 は 128bit 使うぽいじゃん、という程度のことを理解して方針転換。
c4 はかけ算と xor が目に入ったので、 invmod した結果を喰わせてみたらいきなり 0 になる。やる気向上。
c2 は色々入力を与えてみると、どうも本質的に定数と xor してるだけぽかったのだったか、そういう理由で解けた。
c1 は c2 よりややこしくて、入力の 1bit いじると複数 bit が変わるぽかった。まあその変化する bit は固定かな…と適当にやってみると、全然うまくいかない。
とはいえどうも 1bit の入力が変化させる bit 数はたいした数無いぽかったので、 1bit ずつ立てるべきか立てないべきかを手で調整していってしたら解けた。
MQAAAA
謎の Base64 。よくわからんサイトとかひっかかるが、エスパーチックだったのであきらめる。
pieceofeight reloaded
解けなかった。 16パズルの9マスバージョン。解けないようになってると思うので、ゲームを続行するための復活の呪文みたいなやつをリバースエンジニアリングせよって問題かと思ったんだけど、なんでジャンルが Reverse とか Crypto じゃなくて Misc なんだろ…と思いつつ放棄。
i
https://github.com/shinh/mma-ctf-2015/blob/master/gen_q_i.rb
クソ言語で Quine を書けという問題。私にはサービス問題です。2番目に解いたチームだったけど、それは問題が現れた時に寝てたからってだけじゃないかなたぶん
Perfect Matching
https://github.com/shinh/mma-ctf-2015/blob/master/pm.rb
これは今回一番好きな問題だった気がする。
グラフを与えるから完全マッチングをかえしなさい、という問題。グラフとか苦手なので完全マッチングて何だったかなぁ…とか調べたりする。
これ適当に作ったグラフだと完全マッチングができることが保証できないから、なにか問題のグラフには制約がかかってるんだろうな、とグラフを生成するプログラムを読む…普通。というかこの方法だとガチャの原理によりエッジの無いノードすらできるんじゃね?ていうような生成方法。実際できてる。これ普通には無理だ。
…というあたりで、おっとこれは TopCoder じゃなくて CTF だった、ということで解答をチェックする部分の Python コードを読む。うーん正しいように見えるなーと思ってたけど、よく考えるとわかった。
グラフは配列の配列を使ってあらわしていて、最初の配列は頂点IDがインデックスになっていて、2つ目の配列はその頂点と接続されてる頂点IDの列。入力は int(raw_input()) みたいな感じで取ってるから数でないといけないけど、負数がダメとは言ってなくて、配列の負のインデックスを使えば、1つの頂点が2回使えるじゃん! というわけで後は貪欲に取ってけば終わった。
Alphabet Programming
https://github.com/shinh/mma-ctf-2015/blob/master/alpha.rb
アルファベットだけで、 flag というファイルを開く Ruby プログラムを25行以内で書け、という問題。まぁサービス問題…なんだけど最初不注意で大文字が禁止されてると気付いてなかったので、少しムダな時間を使ったりも。
inspect.each を呼んで flag て文字列に破壊的変更して、 each を read に変更しておいてから open self をレシーバに each 、て感じか。