SECCON 2015 Web予選 Writeup
この記事はNomuken氏の温かい手作業で一つ一つ復元されていった記事の一つです.
ポエム
よくよく考えてみると人生二回目のSECCONでした. ふと,Teamの回答状況を眺めながらあぁ去年も似たような回答状況だったなぁと,と反省しています. とはいえ,出来ることも増えてきたりしているので,今後も精進という感じです.
今回もまた,iwasi先輩と自分の2人のCAFEBABEというチームで参加しました. CAFEBABEは,1600点で111位でした.二進数表現を感じる順位でした.
完全に精進が足りない順位なので反省.
自分が解いた問題は以下の通り
- Start SECCON CTF
- Unzip the file
- Connect the server
- Command-Line Quiz
- Entry form
- Exec dmesg
- Decrypt it
(iwasi先輩が解いた問題のwriteupはこちらから)
WriteUp
Start SECCON CTF
ex1 Cipher:PXFR}QIVTMSZCNDKUWAGJB{LHYEO Plain: ABCDEFGHIJKLMNOPQRSTUVWXYZ{} ex2 Cipher:EV}ZZD{DWZRA}FFDNFGQO Plain: {HELLOWORLDSECCONCTF} quiz Cipher:A}FFDNEVPFSGV}KZPN}GO Plain: ????????????????????? There is no bonus in this question
やるだけ,問題文のex1にA-Z{}の対応表が存在するのでそれと照らし合わせていくだけ.
SECCON{HACKTHEPLANET}
Unzip the file
Unzip the file unzip
やるだけ,古来より伝わるpkcrackに突っ込んで終了.
既知の平文を探す際に少々手間取ったが「seccon backnumber」と考えれば,登録したはずなのに突然届かなくなることで有名なメールマガジンのログファイルだと推測できました.
最終的に出てくるflagというファイルですが,MSなWordファイルでした. 開いてみると,白文字でflagが書いてありました. 最後まで手の込んだ仕様で感動しました.
メールマガジンのファイルは2015年の分も含め,2014年のメールマガジンのページからダウンロードが出来ます. 僕は,再度メールマガジンの登録を行いました.
SECCON{1s_th1s_passw0rd_weak?}
Connect the server
login.pwn.seccon.jp:10000
ひとまず,ncで接続.単に平文で通信を行うことを考えれば別にtelnetでも問題はない. 以下は接続時の表示.
どうやらダイアルアップを再現した接続されているサーバのようです.
ログインせずに長い間放置していると以下のような表示が出ました.
It is already in your hands.
とのことですので,どうやら既にフラグは手に入れているようです.
となると,一見見えないところを見る必要があるのでパケットを見てみましょう.
一応,login.pwn.seccon.jp
のIPアドレスを調べておくとwiresharkで検索がしやすいのでおすすめです.
単純にWireSharkでFilterにip.addr == 133.242.228.87
をつっこんで,単純に平文で通信の内容を見るためにFollow TACP Streamをします.
以下はその結果.
SECCON{Sometimes_what_you_see_is_NOT_what_you_get}
Command-Line Quiz
telnet caitsith.pwn.seccon.jp User:root Password:seccon The goal is to find the flag word by "somehow" reading all *.txt files. telnet caitsith.pwn.seccon.jp User:root Password:seccon すべての *.txt ファイルを読め
caitsithと聞いて,熊猫さくら先生を思い浮かべたキャンパーも多かったのでは,と推測します.
ひとまずは,telnetで与えられた情報通りに接続します. 接続したスコアサーバはrootで接続しているにも関わらず,ファイルが読めない強制アクセス権が適用されたサーバに接続されます. おそらく,ホストマシン内にコンテナを用意して,そちらに接続してるんじゃないかなと思いました.
この問題の流れは,/
に存在する問題ファイルを読み,次のステージに進むための回答を環境変数に代入しsh
を起動し進めていくというものである.
各ステージごとに解説を行っていきたい.
Stage1
$ cat stage1.txt What command do you use when you want to read only top lines of a text file? Set your answer to environment variable named stage1 and execute a shell. $ stage1=$your_answer_here sh If your answer is what I meant, you will be able to access stage2.txt file.
ファイルの文頭の内容を確認するのはhead
ですね.
$ stage1=head sh
Stage2
$ cat stage2.txt What command do you use when you want to read only bottom lines of a text file? Set your answer to environment variable named stage2 and execute a shell. $ stage2=$your_answer_here sh If your answer is what I meant, you will be able to access stage3.txt file.
ファイルの文末だけ出してくれるコマンドはtail
ですね.
$ stage2=tail sh
Stage3
$ cat stage3.txt What command do you use when you want to pick up lines that match specific patterns? Set your answer to environment variable named stage3 and execute a shell. $ stage3=$your_answer_here sh If your answer is what I meant, you will be able to access stage4.txt file.
特定パターンに適合する行を取り出すのはgrep
ですね.
これなんですが,最初解いていた時にgrep
と回答したのに不正解扱いにされましたが,時間をおいてやりなおしたらちゃんと解けました.
途中が悪かったのか,もしくはpolicyに不備があって修正されたのか…….
この時はIRC見てなかったのでよくわからないです.
$ stage3=grep sh
Stage4
$ cat stage4.txt What command do you use when you want to process a text file? Set your answer to environment variable named stage4 and execute a shell. $ stage4=$your_answer_here sh If your answer is what I meant, you will be able to access stage5.txt file.
テキストファイルを処理する……と言われてなんなんだという感じですが,答えはawk
でした.
最初,処理も何もという感じだったのでcat
かなと思ったのですが,awk
でした.
$ stage4=awk sh
Stage5
$ cat stage5.txt OK. You reached the final stage. The flag word is in flags.txt file. flags.txt can be read by only one specific program which is available in this server. The program for reading flags.txt is one of commands you can use for processing a text file. Please find it. Good luck. ;-)
最後のflag.txt
を見るためにはテキストファイルを処理する何らかのコマンドを使わなくてはならないそうです.
今までの回答してきたのはもちろんダメでしたし,そもそもcat
もダメでした.
となると,という感じでsed
を使うことで中身を見ることが出来ました.
sed
は文字列を正規表現を利用して置換する超最強かつ強力なツールですが,今回は置換する必要が無いので単純に置換しないように正規表現を書いて中身を見てみましょう.
$ sed "s/(*)/\1/g" flags.txt OK. You have read all .txt files. The flag word is shown below. SECCON{CaitSith@AQUA}
というわけで,フラグは以下の通り.
SECCON{CaitSith@AQUA}
Entry form
http://entryform.pwn.seccon.jp/register.cgi ( Do not use your real mail address.) (登録情報に他人に知られたくないメールアドレスは使用しないでください)
個人的に,うーんって感じの問題でした.
競技後にアクセスしたところ接続を切られてしまうため,画像なしでお届けします.
単純に開くと,メールアドレスとユーザネームを書くとエントリーが完了するというシンプルな問題です.
当初ちゃんとメールが届くのかなと思いましたが,届かなかったです.
途中から(登録情報に他人に知られたくないメールアドレスは使用しないでください)
が追加されて,リアルなメールアドレスを3つ登録してしまった私は涙目になっています.
URLに注目してみると,そもそもcgi
で動作していることが分かります.大方Perlで書かれていると考えられます.
つぎに,アクセス先がDocumentRootではない(つまりregister.cgi
であって/
にアクセスしてない)ので,一度そちらに移動します.
するとregister.cgi_bak
があるので,そのコードを読むことが出来ます.
コード中で注目するべきは,open関数からsendmailを呼び出している点です.
ここまで述べれば,あとは完全に自明でOSコマンドインジェクションを利用してファイルを読みます.
どうやら,誰かがSECRETS/backdoor123.php
というバックドアを置いていたのでそれを利用して,cat ../log
すればflagが得られます.
open関数によるOSコマンドインジェクションはIPAのセキュアPerlプログラミングが参考になります.
Exec dmsg
Please find secret message from the iso linux image. image.zip 秘密のメッセージをLinuxのisoイメージの中から見つけてください。 image.zip
うーん……という感じの問題.
タイトルどおりで,単純にdmsegを実行すれば良い問題.ただし,問題としてはlinuxのiso内にdmesgがインストールされておらず実行に手間取るよねという問題.
一番初めに取った方針はcat /dev/kmsg | grep SECCON
を検討.
ただ,何故かよくわからないけど,うまく行かなかったというか失敗してしまい,面倒くさいと放置して次の日朝起きて解いた.
結局,TinyCoreLinuxをダウンロードしてきて,dmsg
のバイナリをgmailで一度送信してSECCONのイメージに移植というアホとしか言いようがない手法で解いた.
SECCON{elf32-i386}
TLを眺めていると,当初の計画で問題がなかったようで,完全に事故った.
Decrypt it
$ ./cryptooo SECCON{*************************} Encrypted(44): waUqjjDGnYxVyvUOLN8HquEO0J5Dqkh/zr/3KXJCEnw= what's the key? cryptooo.zip
人力で無理矢理解いた.
バイナリに関しては,得意分野ではないのでわからないのだが.
バイナリを調べてみると,64bitなバイナリファイルで,objdumpをしたらmainが無いというバイナリアン向けのバイナリであった.
解くのを諦めようとしたが,どんな時でもその文字列に対して一意な暗号文が返却される(つまり./cryptoo miku
を何度実行しても暗号文は変わらない)という特徴があった.
また,暗号化された文章はどう見てもbase64 encodeされた文字列である.
まとめると……
- 暗号化にrand()は使用されていない(objdumpを呼んでも呼び出されてないし,暗号文は何度呼び出しても変わってない)
- 暗号文は
base64 encoded
なもの
これらを考慮して,数文字ごとの総当り的作戦ができると推測. つまり……
- 与えられたフラグの暗号化後の文字列と
SECCON{[a,b,c...]
のように任意の文字列を追加して暗号化を行った文を比較する. - 部分一致,もしくは完全一致を調べて行って暗号文を確定させていく.
で,実際にpythonのコードを作成しある程度自動化していきました.
実際の作業風景はこちら.
当初,この部分一致も自動化しようと思ったのですが,致命的に頭が悪くロジックが浮かばなかったのでやめました. 今後は頭を良くする方法を考えていきたいです.
その他
一応他に挑戦してたのが,QR puzzle(nonogram)とFragment2,4042をやってました. Fragment2はそもそも論として,頭が致命的に悪くHTTP 2のパケットだと全く考えておらずという感じです. QR Puzzleは向こうの方は完全に正しい(エラーのない)QRコードを出してくるもんだと思って,馬鹿正直にソルバー書いたら,死にました. 4042の方は,RFC4042(April 1 2005となってたのでジョークRFCみたいですね)には気付いたものの,これを解決するスクリプトを書く時間がありませんでした.やはり,人員不足は否めない.
頻繁にQRが出てくるCTFは,SECCONとTDUCTF(LepusCTF)のような気もしますが,ある程度処理を自動化出来るスクリプトを用意したほうが良いなと感じました.
感想(LepusCTFにからめて)
LepusCTFでもCTFの運営をやっていて感じることが,CTFは以下のように部類出来るのではないかな,と.
今回のSECCONは,おそらくはセキュリティ的な問題よりどちらかといえば,コンピュータの深いところの知識を問う「おもしろ系」だったのかな,と感じます. 今回もそうですが「あっ,こんな面白いこともあったのか」という発見もあるので毎度楽しみに参加しています. 個人的にはセキュリティに限らずというところがあるので,面白いなぁと思って参加しています.
とはいえ,SECCONは現状規模が大きく「人材育成が?と言っている手前,どうなんだ」と指摘しているのも見かけました. 自分がとやかく言うつもりはないですが,確かにそうだなぁと思う節もあります.
SECCONのみならず,LepusCTFの方でも今後どういう風に問題を作成していかなきゃいけないのかは毎度悩んでいる節があります. 個人の意見としては,CTFは楽しいものであるべきだと考えているので理想的には楽しかったなぁという感想しか無いように考えていきたいものです.
ともあれ,次回LepusCTFにご期待下さい.
感想(個人的な)
bonsaiがツラすぎたのと,Find the prime numbersもうちょい時間があれば解けたような気がする. うーん,流石に2人だとあまり長く問題にかかりっきりになってしまうとタイムオーバーで解けたはずの問題すら解けなかったみたいなことが起きてしまうので,難しい. やはり,人員が欲しいが各個人のやる気や,タスクに依存するところが多いので下手に人も増やせないと思ったりもする.
bonsai,単純にWebだけしか考えてなかったがNetworkも踏まえて考えると良問だなぁ,と感じた. 正直,今までにないパターンだったので全く考えが及ばなかった. あと,いつもLinuxマンなので1024までのポートでListenするならUAC出るでしょとか考えてたのも敗因かも?
でも,一年間で成長したなと感じたところもあったのでそういう意味ではとても成長を実感できた面白いCTFでした.
今後はチームとして人員不足の解決をしなくてはいけないんだなぁ,と感じました.