EasyCTF 2017 Writeup
先日2017/3/18から3/20の日程で、g0tiu5aというチームでEasyCTF 2017に参加しました。これは私が解いた問題のWriteupです。
チーム全体では2985ポイント。そのうち私は1905ポイントを獲得しました。
最近CTFにはまっていて、今回が初めて真面目に取り組んだ大会でした。常設CTFは現在もいくつかチャレンジしています。
リンク
チームメイトのWriteup (CTFに誘い入れてくれた張本人)
http://jtwp470.hatenablog.jp/entry/2017/03/21/223834
Official Writeups
https://writeups.easyctf.com
問題一覧(フラッグが容易に見れてしまうので注意)
https://github.com/EasyCTF/easyctf-2017-problems
注意点
私はRubyistなので、解答のために書いたスクリプトはほとんどRubyになっています。CTF界隈ではPythonが主流っぽいですが、個人的な慣れを優先しています。書き捨てレベルのコードだとRubyもPythonも大差ないので、読めるかとは思います。
[Miscellaneous 5] IRC
指定のIRCチャンネルに接続して、そこに書いてあるフラッグを入力する。
「最初はIRCかようげぇ……」とか思って放置していたが、ヘッダの “Chat” リンクをクリックしたらWebクライアントがブラウザ上で立ち上がったので簡単に見れた。
[Programming 10] Hello, world!
プログラムに Hello, world!
と表示させる問題。以上。
[Programming 15] Things Add Up
最初に入力回数が与えられ、そのあとの数値を読んで足していくだけ。以上。
[Cryptography 20] Clear and Concise Commentary on Caesar Cipher
DLできるpdfをヒントにフラッグを探す問題。
pdf中に RNFLPGS{LBHTBGVG}
というあからさまな文字列があるので、この暗号を解く。また、同様にそれっぽいURLがある http://www.dcode.fr/caesar-cipher
。シーザー暗号をといてくれるサイトなので、暗号文をこのサイトに食わせると EASYCTFYOUGOTIT
が得られる。これを問題文の注意通り小文字に整形した easyctf{yougotit}
がフラッグとなる。
[Cryptography 20] Flip My Letters
easyctf{r_wlmg_vevm_mvvw_zm_zhxrr_gzyov}
からフラッグを複合する。
タイトル通り、カッコ内のアルファベット順が反転(flip)している。下記のようなコードで複合。フラッグは easyctf{i_dont_even_need_an_ascii_table}
となる。
[Reverse Engineering 25] Hexable
strings
するだけ。 フラグはeasyctf{abcdef__123456}
[Miscellaneous 30] A-maze-ing
迷路の攻略手順がフラッグとなる問題。
正直、どうしてこの問題を解けたのかわからない。 easyctf{j}
で通らず、エラーメッセージとしてNope. The maze is a bit longer than that.
と表示されたので easyctf{jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj}
といった感じにひたすら長い文字列を打って見たら通った。
[Web 30] Cookie Blog
Webページからフラッグを探す問題。
問題名のとおり、Cookieを見るとフラッグやブログの内容が書かれている。
[Reverse Engineering 30] Phunky Python I
Pythonで書かれたコードの動きを解読する問題。
配列 digs
の数値から x
を引いて、その数値をASCIIに変換している。問題文の指定により、出力を easyctf
にすれば良いので、xは4681127626939562201 - 101となる。したがってフラッグは easyctf{4681127626939562100}
[Forensics 50] Mane Event
jpgがらフラッグを探す問題。
strings
をするとフラッグ easyctf{pride_in_african_engin33ring}
が得られる。
[Programming 50] Fizz Buzz 1
単純にFizz Buzzを実装する問題。以上。
[Cryptography 50] RSA 1
RSA暗号を複合する問題。
p,q,e,cが全て与えられているため、ただただRSAを複合化する。コードは拾い物なので割愛する。
[Reverse Engineering 50] Useless Python
テキストを解析する。
まずBase16でエンコードされていると問題文に指定されているので、デコードする。Pythonなら標準装備らしい。Rubyでは base16 gemを使った。デコードすると以下のようなコードになる。
このまま実行しても、どうやら chr(*)
で書いてあるコードがまちがっているらしくエラーが出るので、evalの内部のみを実行する。これが何層にも行われているので、何回も実行する。最終的には以下のコードが得られ、フラッグは easyctf{python_3x3c_exec_3xec_ex3c}
となる。
[Forensics 70] scisnerof
バイナリからフラッグを得る問題。
files
の結果はただのdata、binwalk
でも反応なし。hexdump -C
で眺めていたら、ファイルの末尾がGNP
とPNG
の逆になっていることを発見。バイナリファイルそのものを逆転させる。得られたPNG画像からフラッグを読み取る。フラッグは easyctf{r3v3r5ed_4ensics}
よくよくタイトルを見ると、 forensics
の逆になっている。
[Forensics 75] Petty Difference
2つのテキストファイルからフラッグを探す問題。
問題文に、「この二つは同じに見える」的なことが書かれているので差分をとってみる。普通に diff
コマンドを使うとわからなくなりそうなので、スクリプトを書く。
出力を反転した easyctf{th1s_m4y_b3_th3_d1ff3r3nc3_y0u_w3r3_l00k1ng_4}
がフラッグ
[Cryptography 80] RSA 2
今度はn,e,cが与えられている。nの素因数分解はMsieveにお願いしたら解けた。
[Forensics 80] Flag Collection
DLできるzipファイルからフラッグを探す問題。
解凍すると Thumbs.db
と大量のpng画像が生成される。pngは全て国旗の画像だったため、Thumbs.dbに目をつけた。Thumbs.dbにはサムネイル画像が保持されている(初めて知った)。Thumbs.dbは 7z
で解凍できる(初めて知った)。ただ、解凍ののちに加工が必要で、この記事を参考に編集した。そうするとQRコードの書かれた画像が得られる。QRの内容がフラッグとなる。
[Forensics 85] Zooooooom
DLできるjpgデータを解析する問題。
binwalk
して見ると以下のようになる。
最後のJPEGヘッダ以降を切り出して画像を確認すると、画像にフラッグが書かれている。フラッグはeasyctf{d33p_zo0m_HeKker_2c1ae5}
[Forensics 100] QR 1
DLできる壊れたQRコードを復元してフラッグを得る問題。
QRの位置合わせを行う4箇所のマークが白黒反転しているので、それを直すとQRコードとして成立する。それを読み取るとフラッグが得られる。
[Cryptography 100] Hash On Hash
DLできるテキストからフラッグを複合する問題。
複数のハッシュ値が行区切りで登場する。しかも、同じハッシュ値が何度か出現する。先頭のハッシュ値をGoogleで検索したところ、平文1文字のMD5ハッシュ値だった。下記のようなコードで複合し平文を得た。平文の末尾に書かれている easyctf{1_h0p3_y0u_d1dn7_d0_7h47_by_h4nd}
がフラッグとなる。
[Cryptography 100] Decode Me
暗号文からフラッグを復号化する問題。
文末が =
で終了しているため、Base64で暗号かされていると判断。一度複合しても再度同様の形式だったため、何度かデコードしたらフラッグが得られた。どこぞの常設CTFで見たような問題。
[Web 100] TinyEval
Webページからフラッグを見つけ出す問題。
inputフォームにphpのコードを入れてPOSTするとその文字列をevalしてくれる。ただし文字数制限があり、11文字より多い文字列を実行しようとすると実行前に弾かれる。チームメイトから実行演算子を使ってはどうかとアドバイスを受けた。
まず ls
を実行して見る。
フラッグらしきファイルを発見。ファイル名は直接指定できそうにない長さなので、ワイルドカードを使って乗り切る。
以上の easyctf{it's_2017_anD_we're_still_using_PHP???}
がフラッグ。ポイントとしては、echoの後は空白を入れなくてもバッククォートをうまくパースしてくれるらしい。これでちょうど11文字制限ギリギリで実行できる
[Forensics 100] Ogrewatch
DLしたバイナリからフラッグを見つけ出す問題。
バイナリは files
によるとmkvファイル。動画を再生すると何かのゲームのキャラ画像とともに音声が数秒間再生される。 strings
をして眺めていたら、以下のような文字列を発見。これを整形するとフラッグ easyctf{subs_r_b3tt3r_th@n_dub5}
が得られる。これは字幕情報を示すものだが、字幕ありで再生しても1フレームレベルでしか表示されないため、 strings
で見つけるのが正攻法と思われる。
[Reverse Engineering 115] Phunky Python II
Pythonで書かれたコードの動きを解読する問題。出力が True
となるような jkx
の値を求める。
pork
はjkx - 1
の値となる。ppには素数の配列が格納される。bはjkx * (jkx - 1)
の計算結果の整数を文字列として扱った時に、各文字のindexに相当するppのindexをその文字が示す数だけ掛けた値となる。
よって、bがなるべき指定の値を、素数表の先頭から順に何回割れるか検査することで jkx * (jkx - 1)
を復元できる。
jkx * (jkx - 1)
からjkx
の逆算は、jkx * (jkx - 1)
が jkx * jkx
に近いのを元に頑張る。
[Cryptography 135] RSA 3
2と同様n,e,cが与えられているが、nは十分に長いサイズになっている。こちらのWrite upを参考にFermat法で素因数分解ができた。
[Forensics 150] My USB
USBのイメージデータがDLできる。そこからフラッグを探す。
Autopsyで開いて画像を眺めたらフラッグが書かれていた。あとで普通にmountしてみたが、その画像は見れなかった。
[Cryptography 230] Genius
指定のWebページにアクセスするとHash値が与えられる。Hash前の文字列を求めて、Webページのinputフォームから送信するとフラッグが得られる。
HTMLを見ると、Hash化の手順がjsでコーディングされていた。Hash化の手順は、平文を4文字づつに分割し、それぞれを何かのHash関数に投げ、そのハッシュ関数の結果文字列を結合するというものだった。4文字づつHash関数に投げていたので、4文字づつ貪欲に探索していくことにした。初めはjsのコードを使って探索を試みたが、遅すぎて探索できなかった。
既存のHash関数をjsで実装しただけなのではないかと思いつき調べた。Hash値が16進数なこと、ダイジェスト長が128bitであることを元に調べると既存手法ではMD5が該当した。jsのコードとWikipediaを見比べると合致したため、MD5と断定。下記のようなRubyコードを書いて探索した。
疲れていたのか、実行毎に知りたい部分をソースコードに書いておく実装になったが、地道に実行した。Hash前の文字列は以下のとおり。
あとはこれをWebフォームから送るとフラッグが得られる。
Writeupは以上。