In the Spica (Satellite)

気になることを書いていた日記のレスキュー版です

SECCON 2015 Web予選 Writeup

この記事はNomuken氏の温かい手作業で一つ一つ復元されていった記事の一つです.

ポエム

よくよく考えてみると人生二回目のSECCONでした. ふと,Teamの回答状況を眺めながらあぁ去年も似たような回答状況だったなぁと,と反省しています. とはいえ,出来ることも増えてきたりしているので,今後も精進という感じです.

今回もまた,iwasi先輩と自分の2人のCAFEBABEというチームで参加しました. CAFEBABEは,1600点で111位でした.二進数表現を感じる順位でした.

f:id:nmkn:20151216202147p:plain

完全に精進が足りない順位なので反省.

自分が解いた問題は以下の通り

  1. Start SECCON CTF
  2. Unzip the file
  3. Connect the server
  4. Command-Line Quiz
  5. Entry form
  6. Exec dmesg
  7. 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に突っ込んで終了.

f:id:nmkn:20151216202002p:plain

既知の平文を探す際に少々手間取ったが「seccon backnumber」と考えれば,登録したはずなのに突然届かなくなることで有名なメールマガジンのログファイルだと推測できました.

最終的に出てくるflagというファイルですが,MSなWordファイルでした. 開いてみると,白文字でflagが書いてありました. 最後まで手の込んだ仕様で感動しました.

メールマガジンのファイルは2015年の分も含め,2014年のメールマガジンのページからダウンロードが出来ます. 僕は,再度メールマガジンの登録を行いました.

SECCON{1s_th1s_passw0rd_weak?}

Connect the server

login.pwn.seccon.jp:10000

ひとまず,ncで接続.単に平文で通信を行うことを考えれば別にtelnetでも問題はない. 以下は接続時の表示.

f:id:nmkn:20151216202027p:plain

どうやらダイアルアップを再現した接続されているサーバのようです.

ログインせずに長い間放置していると以下のような表示が出ました.

f:id:nmkn:20151216202100p:plain

It is already in your hands.とのことですので,どうやら既にフラグは手に入れているようです. となると,一見見えないところを見る必要があるのでパケットを見てみましょう.

一応,login.pwn.seccon.jpIPアドレスを調べておくとwiresharkで検索がしやすいのでおすすめです.

f:id:nmkn:20151216202133p:plain

単純にWireSharkでFilterにip.addr == 133.242.228.87をつっこんで,単純に平文で通信の内容を見るためにFollow TACP Streamをします.

以下はその結果.

f:id:nmkn:20151216202244p:plain

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なもの

これらを考慮して,数文字ごとの総当り的作戦ができると推測. つまり……

  1. 与えられたフラグの暗号化後の文字列とSECCON{[a,b,c...]のように任意の文字列を追加して暗号化を行った文を比較する.
  2. 部分一致,もしくは完全一致を調べて行って暗号文を確定させていく.

で,実際にpythonのコードを作成しある程度自動化していきました.

実際の作業風景はこちら.

f:id:nmkn:20151216202336p:plain

当初,この部分一致も自動化しようと思ったのですが,致命的に頭が悪くロジックが浮かばなかったのでやめました. 今後は頭を良くする方法を考えていきたいです.

その他

一応他に挑戦してたのが,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は以下のように部類出来るのではないかな,と.

  1. 「ユニーク系(絶対起きないセキュリティホール)」
  2. 「現実系(起きうる,もしくは脆弱性が発生したシナリオが明確)」
  3. 「おもしろ系(あまりセキュリティ等を考えていない)」

今回のSECCONは,おそらくはセキュリティ的な問題よりどちらかといえば,コンピュータの深いところの知識を問う「おもしろ系」だったのかな,と感じます. 今回もそうですが「あっ,こんな面白いこともあったのか」という発見もあるので毎度楽しみに参加しています. 個人的にはセキュリティに限らずというところがあるので,面白いなぁと思って参加しています.

とはいえ,SECCONは現状規模が大きく「人材育成が?と言っている手前,どうなんだ」と指摘しているのも見かけました. 自分がとやかく言うつもりはないですが,確かにそうだなぁと思う節もあります.

SECCONのみならず,LepusCTFの方でも今後どういう風に問題を作成していかなきゃいけないのかは毎度悩んでいる節があります. 個人の意見としては,CTFは楽しいものであるべきだと考えているので理想的には楽しかったなぁという感想しか無いように考えていきたいものです.

ともあれ,次回LepusCTFにご期待下さい.

感想(個人的な)

bonsaiがツラすぎたのと,Find the prime numbersもうちょい時間があれば解けたような気がする. うーん,流石に2人だとあまり長く問題にかかりっきりになってしまうとタイムオーバーで解けたはずの問題すら解けなかったみたいなことが起きてしまうので,難しい. やはり,人員が欲しいが各個人のやる気や,タスクに依存するところが多いので下手に人も増やせないと思ったりもする.

bonsai,単純にWebだけしか考えてなかったがNetworkも踏まえて考えると良問だなぁ,と感じた. 正直,今までにないパターンだったので全く考えが及ばなかった. あと,いつもLinuxマンなので1024までのポートでListenするならUAC出るでしょとか考えてたのも敗因かも?

でも,一年間で成長したなと感じたところもあったのでそういう意味ではとても成長を実感できた面白いCTFでした.

今後はチームとして人員不足の解決をしなくてはいけないんだなぁ,と感じました.