スマートフォン解析 top

TOP > タイガーチームセキュリティレポート > Reflected File Downloadの問題

タイガーチームセキュリティレポート

Reflected File Downloadの問題

RFD(Reflected File Download)はBlack Hat Europe 2014で発表されたWebアプリケーションの脆弱性です。今回はOren Hafifが発表したこの脆弱性を紹介します。


このRFDは、ごく簡単に言ってしまうと攻撃者の入力値を含むWebページからのレスポンスを指定したファイル名でダウンロードさせ、ユーザがそれをクリックすることでダウンロードしたファイルを実行させる攻撃です。

RFDに対して脆弱なWebページの条件は3つに集約することができます。

1. Reflected - ユーザの入力値をレスポンスの一部に含むこと。
2. Filename - Webページのファイル名を任意に指定できること。
3. Download - ブラウザがレスポンスをダウンロードすること。

条件1は多くの動的ページが満たす条件です。動的ページは入力値をもとに生成されるので。条件2はあとで触れますが、URLのファイル名を変えながら同じWebページにアクセスできる場合があります。条件3は、おもにContent-Typeに関する条件です。

まず条件2について、少し詳しく検討していきます。

RESTful APIでは、URLのpath componentsがAPIのパラメータとして使用されることが多いですが、そのようなAPIにはURLのマッピングを厳密に行っていないものがあります。例えば以下のような2つのパラメータをとるAPIを考えてみます。

http://example.com/<endpoint>/<verb>/<arg0>/<arg1>

このAPIでは2つのパラメータ<arg0>と<arg1>を指定できることになっていますが、<arg1>に任意のファイル名を指定できる場合、または<arg2>以降のパラメータを追加しても無視される場合、条件2を満たします。例えば以下のようなURLです。

http://example.com/<endpoint>/<verb>/<arg0>/xxx.bat
http://example.com/<endpoint>/<verb>/<arg0>/<arg1>/xxx.bat

いずれも、ファイル名にcmd.exeに関連づけられた拡張子.batを指定しています。このようなAPIの具体例はこのあとで示すことにします。

また、Webサーバにはpath infoをサポートするものがあります。path infoはURLのファイル名のうしろに追加されるpath形式の情報です。

例えばApacheではAcceptPathInfoディレクティブでpath infoの扱いを制御します。デフォルトでは静的コンテンツでpath infoが無効になっていますが、phpやcgiなどではpath infoが有効です。これはそれぞれのcontent handlerに依存するところですが、Webサイト全体で無効化することもできます。

以下はphpinfo()を実行するだけのphpプログラムinfo.phpにpath infoとして/xxx.batを追加してアクセスしたものです。この場合、ファイル名はinfo.phpではなくxxx.batになります。path infoが無効であれば404 Not Foundとなるところです。

path infoに関連して、Tomcatなどのservlet containerはpath parametersをサポートします。これはほとんどの場合、Cookieをサポートしないブラウザでセッションを維持するためにファイル名のうしろに追加される;jsessionid=<session id>形式のセッションIDとして現れます。

この場合もpath infoの場合と同様に、;のうしろにjsessionidではなくファイル名を指定することでそれをブラウザにファイル名の一部として解釈させることができます。例えば、以下のようなURLです。サーバ側ではURLの;以降の部分は無視されます。

http://example.com/example.jsp;%2fxxx.bat;%2fxxx.bat

これまでファイル名としてxxx.batを使ってきましたが、これはバッチファイルがWindows上での最も(構造的に)単純で一般的な実行形式のひとつと考えられるからです。

そこで以下では単純化の為にファイル名の拡張子を.batに限定して考えることにすると、条件1、3で言及しているレスポンスは部分的にバッチとして実行実行可能な形式である必要があります。

例えばHTMLファイルはどうでしょうか。

通常HTMLファイルの先頭付近には<html>が存在しますが、これをバッチファイルとして解釈しようとすると構文エラーとなり、それ以降の部分は無視されてしまいます。レスポンスに含まれる入力値は、<html>を含まないエラーメッセージなどを除けばほとんどの場合<html>以降に現れますから、HTMLはバッチとして実行できません。

RFDの対象としてもっと有力な候補はjson形式のレスポンスです。例えば、以下は"||calc||をエスケープして格納したjsonレスポンスです。

["\"||calc||"]

{"key" : "\"||calc||"}

これらをバッチとして実行すると以下のように電卓が起動します。double quoteされた文字列をバッチのcontextでコマンドとして解釈されないようにするには、jsonで広く使われているbackslash escapeではなくhex encodeがより適切です。

最後に、条件3についてはContent-Type以外に考慮すべき重要な例外があります。

Google ChromeとOperaではanchor tagにdownload属性を指定することで、リンクをクリックした際にContent-Typeの指定を無視してしてブラウザにダウンロードを強制することができます。


一つの具体例で検証してみます。

以下は任意の個数の引数をとるAPIの例です。

http://example.com/api/example/<arg0>/<arg1>/.../<argN>

このAPIは<arg1>以降のN個の引数をjson形式のレスポンス(配列)で返します。Content-Typeはapplication/jsonにしています。以下は実際にこのAPIを呼び出した結果の画面です。

<arg1>に相当するyyyと<arg2>に相当するzzzが格納されたjsonレスポンスが返ってきました。ここでyyyの代わりに"||calc||、zzzの代わりにsetup.batを指定した結果が以下の画面です。

ここではレスポンスがダウンロードされずに画面上に表示されていますが、以下の罠ページでdownload属性を指定したリンクclick meをクリックすることで、上のjson形式の結果がsetup.batというファイル名でダウンロードされます。

<html><body>
<a download href=“http://example.com/api/example/xxx/%22%7c%7ccalc%7c%7c/setup.bat”>click me</a>
</body></html>

ダウンロードしたファイルsetup.batをクリックすると、ファイルを実行する前に警告が表示されます。

ここで警告を無視して「実行」をクリックするとsetup.batが実行されて電卓が起動します。同じ方法で電卓の代わりに任意のコマンドを実行することができます。

また、以下は同じAPIに不正なパラメータを指定した際のエラーメッセージです。このレスポンスでも同様にRFDを実行することが可能です。

ここではGoogle Chromeで検証しましたが、IEの場合にも触れておくべきだと思ったので補足します。IEだとdownload属性は無視されますが、Content-Typeがapplication/jsonであるためアクセスすると自動的にファイルがダウンロードされファイルを実行するかどうか聞かれます。

(参考までに)IEに関してはこのような場合にCaptchaに偽装してファイルの「実行」を選択させるkey jackingと呼ばれる手法[3]が知られています。また、他のContent-Typeの場合についても調査した結果[1]があります。筆者はapplication/json以外の場合については検証していません。


[1]、[2]で推奨されているのは以下の対策です。いくつかは上でも触れていますが、それ以外の対策も含め以下に列挙します。一部コメントを入れていますが詳細は[1]、[2]で確認してください。特に、[2]ではRFDを利用した興味深いexploitが紹介されています。

・Use exact URL mapping
・Do not escape! Encode!
・Add Content-Disposition with a "filename" attribute for APIs (安全なファイル名を強制する)
・Whitelist Callbacks (JSONPでRFDを防ぐために)
・Require custom headers
・Never include user input in API usage errors
・Remove support for Path parameters
・Add X-Content-Type-Options (MIME sniffingを無効化する)

最後に、上記の対策のいくつかはAPIにおけるXSS対策としても効果があることを付け加えておきます。


参考情報:
[1] Reflected File Download a New Web Attack Vector
https://www.blackhat.com/docs/eu-14/materials/eu-14-Hafif-Reflected-File-Download-A-New-Web-Attack-Vector-wp.pdf
[2] Reflected File Download A New Web Attack Vector
https://www.blackhat.com/docs/eu-14/materials/eu-14-Hafif-Reflected-File-Download-A-New-Web-Attack-Vector.pdf
[3] Anatomy of a browser trick - you've heard of "clickjacking", now meet "keyjacking"...
https://nakedsecurity.sophos.com/2013/06/29/anatomy-of-a-browser-trick-youve-heard-of-clickjacking-now-meet-keyjacking/


タイガーチームメンバー 塚本 泰三