CTFに参加してきた
Cyber Wargame Christmas Partyに参加したぞい。
CTF
Capture The Flagの略らしい。隠された答え(Flag)を様々な手法を用いて探す競技、だと思う。俺はこのイベント参加するまで経験0だった。
内容
会場内はいくつかのテーブルが存在し、分野で分かれているようだった。俺はそのうちの初心者テーブルを選択した。当日やったことは、overthewire wargamesっていうCTFをハンズオンで学べるサイトの、最も簡単なステージBanditをひたすら解いていった。本記事では当日解けなかった問題をwrite upしていこうと思う。
Level0 〜 Level12
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…(必死に解いてる)