初CTF

Posted on

CTFに参加してきた

Cyber Wargame Christmas Partyに参加したぞい。

CTF

Capture The Flagの略らしい。隠された答え(Flag)を様々な手法を用いて探す競技、だと思う。俺はこのイベント参加するまで経験0だった。

内容

会場内はいくつかのテーブルが存在し、分野で分かれているようだった。俺はそのうちの初心者テーブルを選択した。当日やったことは、overthewire wargamesっていうCTFをハンズオンで学べるサイトの、最も簡単なステージBanditをひたすら解いていった。本記事では当日解けなかった問題をwrite upしていこうと思う。

Level0 〜 Level12

隣にいたHagiが書いてくれてる

Level12 -> Level13

どうやらdata.txtは16進ダンプされてるらしい。問題ページに書かれてあるCommands you may need to solve this levelのコマンドをググると、xxdコマンドが16進ダンプに関係しているらしい。というわけで

xxd -r data.txt >hoge

homeディレクトリにはファイルを生成できない!

問題文を読むと、/tmp 下にディレクトリ作っていいよ〜って書いてあるので作ろう(同名のディレクトリが先に誰かに作られてるかもね)。

mkdir /tmp/hoge
cd /tmp/hoge

このディレクトリ内だったらファイルの生成権限があるので改めて

xxd -r data.txt >hoge

デコードされたhogeは人間が読めるテキストファイルじゃないっぽいので

file hoge

すると、このファイルはgzip形式で圧縮されたファイルらしい。gzipコマンドは拡張子が.gzのファイルじゃないと解凍できないっぽいので

mv hoge hoge.gz
gzip -d hoge.gz

lsコマンドで見ると解凍されたhogeがあるので

file hoge

bzip2形式で圧縮されたファイルらしい。

bzip2 -d hoge

hoge.outが生成される。これはgzip形式なので

mv hoge.out hoge.gz
gzip -d hoge.gz

ここで解凍されたhogeはtar形式の圧縮ファイルらしい。ちなみにgzipにしろbzipにしろとりあえずhelpコマンドでオプション確認してるんだけど、tar --helpだけめっっっっっっちゃ長くてびっくりした。

tar -xf hoge

data5.binが生成される。これもtar形式なので

tar -xf data5.bin

data6.binが生成される。これはbzip2形式なので

bzip2 -d data6.bin

data6.bin.outが生成される。これはtar形式なので

tar -xf data6.bin.out

data8.binが生成される。これはgzip形式なので

mv data8.bin data8.gz
gzip -d data8.gz

ここで生成されたdata8はASCII textで、中身をみるとようやくパスワードが手に入る。くぅ〜疲れましたwこれにて完結です!

Level13 -> Level14

ここではLevel14へ接続するパスワードは手に入らないみたい。代わりにsshの秘密鍵があるのでこれを駆使しよう。
コマンドをググるとsshは-iオプションで秘密鍵を指定してのログインができるらしい。先程のファイルの内容をコピーしたらexitで抜ける。

cat > sshkey.private
chmod 700 sshkey.private

で標準入力状態になるのでさっきの秘密鍵の内容をペースト(—-BEGIN RSA PRIVATE KEY—–とかの行も含めるよ)。あと権限が広いとbanditに接続したときにwarningされるのでchmodで所有者以外の権限を消しとく。

ssh [email protected] -p 2220 -i sshkey.private

終了。

Level14 -> Level15

bandit15のパスワードは、bandit14のパスワードをlocalhostのポート30000に提出したら返ってくるらしい。bandit14のパスワードはLevel13 -> Level14の問題文にその所在が書かれていて

cat /etc/bandit_pass/bandit14

で確認できる。

提出???

提出(submitting)ってなんだ???よくわからないのでコマンドをググる。telnetかncあたりを使いそう。結局どっちのコマンドでも出来た。

(telnet localhost 30000)
nc localhost 30000

入力待ちになるので、Bandit14のパスワードをペーストしてEnterをッターンすると、Correct!って返ってきてBandit15のパスワードを獲得できる。

Level15 -> Level16

今度はBandit15のパスワードをlocalhostの30001番に、SSL形式で送信したら良いらしい。
Siguniang’s Blog を参考に

openssl s_client -connect localhost:30001

を叩くとSSL接続の情報が流れた後入力待ち状態になるのでbandit15のパスワードをsubmit。するとこんなものが返ってくる。

HEARTBEATING
read R BLOCK

問題ページに、上のような文言が返ってきたら-ign_eofオプション使えって書いてあるので使う。

openssl s_client -connect localhost:30001 -ign_eof

今度は成功。bandit16のパスワードを獲得できた。

-ign_eof

ちなみに今回使ったこのオプション、何者なのか?[UN-SOFT’s](オレオレ証明書使ってるからか、Chromeだと警告が出る)によると

このコマンドというかオプションを使う時に-ign_eofというサブオプションをつけないと、行頭、より正確に言えばCRLF直後の1文字が大文字のRだとSSLの再接続、大文字のQだとSSLの切断(STARTTLSの反対でENDTLSとでも言うような動き)、というのは割といろいろなサイトに書かれている。

ということらしい。

Level16 -> Level17

Bandit16のパスワードをlocalhostの31000から32000番のどれかに送信すると、Bandit17の資格情報(credentials)をもらえるらしい。最初に開いてるポートを探して、その中でSSLが喋れるポートを探すって。-pオプションを付けないと31000〜32000のポートの状態を教えてくれないので

nmap -p 31000-32000 localhost

5個空いてるポートがあるな〜。どれが正解か分からんので上から順にopenssl s_client -connect localhost:ポート番号 -ign_eofでパスワードを送りつけてみればそのうち秘密鍵が得られる。その内容をコピーして、exit。cat >private.sshで内容をペーストして

ssh [email protected] -p 2220 -i private.ssh

Level17 -> Level18

ホームディレクトリにpassword.oldとpassword.newの2つのファイルが存在し、oldからnewの変更差分がパスワードだよってことらしい。なので

diff password.old password.new

でOK。

Byebye!

今回ゲットしたパスワードを使ってbandit18にログインしようとすると Byebye!という文言とともに接続が切られてしまう。問題ページにもあるように、これは次の問題に関係しているようだ。

Level18 -> Level19

次のパスワードはホームディレクトリのreadmeに書いてある。でも.bashrcの記述によって、ssh接続したらログアウトさせてしまうようになっているらしい。どうしたもんかなぁと頭を悩ませていたが、ssh経由でコマンドを実行出来るらしい。

ssh [email protected] -p 2220 cat readme

これでbandit18のパスワードを入力してログインしたらcat readmeが実行される。

Level19 -> Level20

次のレベルに行くにはホームディレクトリにあるsetuid binaryを実行すれば良い?らしい。とりあえず

./bandit20-do

で使い方が表示される。どうやら./bandit20-do commandで、bandit20としてコマンドを実行できるっぽい。bandit20のパスワードは /etc/bandit_pass/bandit20 にあるので

./bandit20-do cat /etc/bandit_pass/bandit20

でOK。

Level20 -> Level21

Coming soon…(必死に解いてる)