2013年08月30日

ロリポップでWordPressの改竄が拡がった理由

ロリポップでの大規模なWordPressサイトの改竄について
http://lolipop.jp/info/news/4149/

ロリポップからのリリースでは、管理パスワードとログインへのアクセス制限の強化を推奨して、パーミッションの変更と全体のウイルスチェックを行うとしている。WordPressそのもののアップデートはマニュアルに方法が記載されているものの、リリースでは触れられていない。
このことから、被害が大きくなったのは、ロリポップの提供していたWordPressのインストール手順に問題があり、wp-config.phpなどのファイルのパーミッションが不適切だったためではないかと推察出来る。


いくつかのアカウントだけWordPressの管理パスワードが突破される、というのであれば、世界中でほぼいつでも起こっている。
もし、あるユーザーの管理パスワードが脆弱で推測することが出来てしまうと、そのWordPress管理画面から自由にプラグインを導入できる。古い脆弱なWordPressやプラグインを使っている場合も同様で、この場合、そのユーザーアカウントで攻撃者は任意のスクリプトを実行でき、ファイルやDB上のデータ全てを自由に改竄可能になる。
ここまでは、ロリポップに限らずどこのホスティングサービスでも起こりうる、脆弱なパスワードあるいは古いバージョンを使っているユーザーの自己責任と言える。

安価な共用サーバーでのウェブホスティングでは、数多くのユーザーが一つのサーバーを利用している。一つのアカウントに侵入されても、同一サーバーの他のユーザーのデータを読まれたり、変更されたりしないように、CGIは各ユーザーの権限で動作させ、ファイル・ディレクトリの所有者がパーミッションでアクセスを制限することで、他のユーザーの秘密のデータを保護している。そのため、(脆弱な)あるユーザーの権限でCGIが実行できても、影響範囲はそのユーザー1人にとどまる。
(ユーザー毎のchroot/jail/LXCなどを利用ことで、パーミッションに依存せず、各ユーザのデータを保護しているところも有るだろうが、少なくともロリポップはそうでは無かったことになる)

しかし、wp-config.phpに不適切なパーミッション(たとえば444、サーバー上の全てのユーザーが読み込み可能)が設定されていて、そのファイルの場所が分かっていれば、他のユーザーがスクリプトの内容を読めてしまう。wp-configにはデータベースに接続するためのパスワードが記載されているので、DBに接続して管理パスワードを変更してしまえば、管理者としてログインしてウェブサイトを改ざんできる。

つまり、WordPressをインストールしたユーザーのうち、たった1人が脆弱なパスワードを利用していたり脆弱な古いバージョンを使っていて、ファイルのパーミッションが不適切であれば、同じサーバーのユーザーが芋づる式に二次被害を受けることになる。
対策として、真っ先にアナウンスされた内容はWordPressのアップデートを推奨するもの(WordPress自体の脆弱性対策)ではなく、強い管理パスワードとパーミッションの再設定を求めるものだったことから、この推測が補強される。

ロリポップにWordPressをインストールしたユーザーの多くが、誤ったパーミッションを設定していた理由は幾つか想像できる。単にユーザーの不注意かも知れないし、ロリポップへのWordPressインストール方法を紹介したサイトが、間違ったパーミッション設定を多数のユーザーに伝授してしまったのかもしれない。

しかし最もありえそうなのは、ロリポップの「WordPress簡単インストール」機能に問題があり、ユーザーのwp-config.phpに不適切なパーミッション(たとえば644)を設定してしまった場合。
ロリポップのWordPressインストール手順にはインストール後のパーミッションの変更が記載されていなかったので、ユーザーはそうと気付かずに、インストーラが設定した不適切なパーミッションのまま運用していた、と考えられる。

WordPressの簡単インストール機能がどのように動作するのか、現在その機能が無効化されていて確かめることが出来ないが、ほぼ同様の動作をするだろうMovableTypeの簡単インストール機能は有効で、自動的にDBアカウントとパスワードが記入される mt-config.cgi のパーミッションは644のままだった。ユーザー権限でCGIを動作させている共用サーバでは通常、400(所有者のみ読み出し可能)に変更するはずだ。
wp-config.php のパーミッションを400にする必要があるのに、同じ方法でDBに接続するMovableTypeは変更する必要が無いというのが不思議なところだ。二次被害を引き起こした可能性がある以上、WordPressにかぎらず全てのインストール機能は無効化して、全てのファイルのパーミッションの再確認をするべきだ。


上記の推測があたっているとすると、ユーザーが強固なパスワードを使っていて、手順通りに最新バージョンで運用していても、脆弱なユーザーの二次被害を受けることになる。
(追記)
各サーバーで最初に侵入されたアカウントへが侵入経路がWordPressの脆弱性であろうと、それ以外であろうとも関係は無い。
(/追記
thx:名無しさん

ユーザー側でとれる対応は、
・wp-config.phpやmt-config.cgiなど、同一サーバーの他のユーザーに見られては困るファイル(管理パスワードやDBパスワードを記述したファイル)のパーミッションを400に制限する(脆弱なユーザーからの二次被害対策)
・手元のバックアップと現状のファイル・DB内データを比較し、改竄があればバックアップから復元する(バックドアや不正なリンク設置への対策)
・DB接続用パスワードも強固なものに変更する(対応するwp-config.phpの記述も変更する)


現状のロリポップの記載内容では、改ざんされたウェブサイトの所有者全員が脆弱なWordPressプラグイン・テーマを使っていたかのように書かれている。WordPress以外のCGIスクリプトにも同じ問題が起きていないかのチェックがなされていない、というのは問題だと思うのだが。
posted by ko-zu at 00:30| Comment(2) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2013年08月22日

OpenIDの仕組み・安全性と危険性

少し思う所があってメモ

OpenIDが出来る事

ユーザーが「あるOpenIDプロバイダにアカウントを持っていること」をウェブアプリに証明する

基本的にはたったこれだけ。OAuthとの違いウェブアプリに何らかの権限や、ランダム生成された識別子以上の情報を渡すことはない。

OpenIDログインを利用するウェブアプリ(リライングパーティー)が知ることができるのは
・ユーザーがどのプロバイダのIDを持っているか
・ユーザーの所有する識別子(乱数)

OpenIDを発行する側(OpenIDプロバイダと呼ばれる)が知ることが出来るのは、
・ユーザーがどのウェブアプリ(リライングパーティーと呼ばれる)にアクセスしたか

だけになる。正しく実装されたOpenIDでは、OpenIDプロバイダにどのような情報が登録されているか(メールアドレスやパスワードなど)は、リライングパーティにはわたらない


仕組み
OpenIDではおおよそ次のような認証手順をふむ。

ユーザーがリライングパーティのウェブサイトにアクセスする。

ユーザーが「OpenIDでログイン」を選択
= ユーザー→リライングパーティ「私はとあるプロバイダが発行したOpenIDを持っています」

リライングパーティはブラウザをOpenIDプロバイダのページへリダイレクトする
=リライングパーティ→ブラウザ「問い合わせメッセージを渡すので、それに署名してもらってきてください」

ここからブラウザはOpenIDプロバイダのページを表示する

ブラウザはリライングパーティが発行したメッセージへの署名要求を送る
=ブラウザ→プロバイダ「このメッセージに、アカウントを持っていることを証明する署名をください」

OpenIDプロバイダはOpenIDプロバイダ自身のログイン画面を表示する
=OpenIDプロバイダ→ユーザー「あなたは誰ですか?」

ユーザ―はOpenIDプロバイダでのIDとパスワードなどを入力する
=ユーザー→OpenIDプロバイダ「ユーザーID foo、パスワードbarです。」

OpenIDプロバイダはユーザーへの確認画面を表示する
=プロバイダ「このウェブアプリ(リライングパーティ)に対してあなたの識別子を証明していいですか?」

ユーザーがOKをクリック

OpenIDプロバイダはメッセージへの署名と識別子をブラウザに渡す
=プロバイダ→ブラウザ「この署名と識別子を持ってリライングパーティのページに行ってください」

ここからブラウザはリライングパーティのウェブページにもどる

ブラウザは署名済みメッセージをリライングパーティに送る
=ブラウザ→リライングパーティ「このOpenID識別子をもっている事を証明します」

リライングパーティはサードパーティの署名を検証して、識別子とユーザーを紐つけて保存する。

これでリライングパーティは、「ユーザーがOpenIDプロバイダにアカウントを持っていること」と「ユーザーの(ランダム生成された)識別子」を保証できる。

OpenIDプロバイダに保存されている情報は、ユーザーの識別子以外、なにも漏れていない。例えば、Google発行ののOpenIDを使っても、GmailアドレスやGoogle+アカウントの個人情報が漏れることは無い。

具体的方法は
http://openid-foundation-japan.github.io/openid-authentication.html
に日訳があった。


OpenIDの問題点
現在普及していないことから分かるように欠点もある。

2つのウェブアプリの間での紐付け
古いOpenID実装では、ユーザーは一つのOpenIDプロバイダにたった一つだけ固有の識別子をもつ。つまり、2つのウェブアプリが提携すると、それぞれにログインしたユーザーが同一人物であることをOpenID識別子が一致することから知られてしまう。(もっとも、サードパーティクッキーやIPアドレスによる追跡の方がずっと強力だが)

OpenIDプロバイダはこの問題に、リライングパーティ毎に個別の識別子を生成することで対処できる。つまり、あるウェブアプリAにユーザーfoobarがログインする時にはOpenID識別子として123456を返し、ウェブアプリNには7890123、というふうにしてしまえば、識別子から紐付けされることはない。OpenID2.0では、ユーザーはOpenIDプロバイダの名前さえ覚えておけば、識別子はOpenIDプロバイダが自動生成してくれる。


ユーザーの誤認・フィッシング

OpenIDを実装すると、異なるウェブサイト間をリダイレクトで自動的に移動することになる。これはユーザーを混乱させる元になる。

悪意あるリライングパーティは、OpenIDプロバイダにリダイレクトしたと見せかけて、プロバイダのログイン画面を模倣したフィッシングサイトにユーザーをリダイレクト出来る。
直接的な対処法がなく、ユーザーにフィッシング対策の知識が一定以上有ることを期待するしかない。OpenIDプロバイダになる=フィッシングリスクを高める事になり、一般向けに開放することが難しい。

逆向き(OpenIDプロバイダからリライングパーティ)も同様で、信頼出来ないOpenIDプロバイダが、リライングパーティを模倣したフィッシングサイトを作ることで、ユーザーがリライングパーティにポストしようとした内容を詐取する可能性がある。

OpenIDを導入するにあたっては、リダイレクト前後に特徴的なページ(例えば、ユーザ専用のアイコン画像や背景色など)を挿入するなど、ウェブサイトの識別性を高めるフィッシング対策をとる必要がある。
例えば、Yahooはログイン画面に好きな画像を登録できる。


OpenIDプロバイダの信頼性
OpenIDプロバイダが侵入されるなどで、認証システムが乗っ取られると、そのOpenIDを利用してログインしている全てのウェブアプリが同時に脅威にさらされる。
OpenIDの原理上、OpenIDプロバイダにはどのリライングパーティにアクセスしたかの履歴が残るので、侵入に成功した攻撃者は入手したOpenIDでどのウェブサイトにログイン出来るか瞬時に分かってしまう。

通常のパスワード漏洩では、他のサイトはログイン失敗したパスワードのパターンを調査することで、漏洩リストによる攻撃の徴候を検出することが可能だが、OpenIDプロバイダ自体の脆弱性ではそもそもログインに失敗することが無いので、不正ログイン検出が難しくなる。

対処法としては、プロバイダの脆弱性が発覚した時点でリライングパーティ側は該当するOpenIDプロバイダのユーザー全員をログアウトさせ、OpenIDプロバイダの信頼性が復旧した後にログインし直す事を要求する。


OpenID認証の代替手段
OpenIDプロバイダがクラックされた場合、上記のように一時的とはいえリライングパーティ側は、そのOpenIDプロバイダを利用した認証を無効化する必要に迫られる。(念の為、OpenIDプロバイダ側に総パスワードリセットなどの復旧手段があれば、アカウントが完全に失われることは避けられる) ユーザー認証を完全にOpenIDに頼っている場合、その間ユーザーが安全にログインする手段がなくなってしまう。

リアルタイムのアクティブアユーザー数が直接利益に関わるウェブアプリでは、アカウントを失うリスクを減らすために、リライングパーティ側でも、ユーザーのメールアドレスなど、ユーザーへの信頼出来る到達手段を用意しておく必要があり、これはOpenIDの利点を相殺する。


サードパーティ認証との識別性
OpenIDそのものの認知度が低く、単なるサードパーティ認証やOAuthとの違いがユーザーに理解されていない。
そのため、メールアドレス漏洩やアカウント機能の不正利用についての懸念がOpenIDの利用を阻害する。
ラベル:OpenID
posted by ko-zu at 00:41| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2013年08月10日

サーバー側・クライアント側でのBEAST/CRIME系攻撃への処方メモ

今更過ぎるけれど、centos6.xのopensslがまだ1.0.0でTLS1.1非対応という現実に直面したので回避方法を考えてみるメモ。

(追記:ブラウザ側でのハックの困難性があまりに甘かったので困難性を追記。)


BEASTやCRIME攻撃として提案された手法の本質は、同じ秘密情報を含むHTTPSリクエストをたくさん発生させることで、SSL圧縮ブロックや暗号ブロック境界の選択平文攻撃によって、秘密情報を1バイト単位で少しずつ盗むというものだ。
http://j-net21.smrj.go.jp/develop/digital/entry/001-20120229-01.html
CRIMEなら例えば、リクエストに適当な文字列を1バイト追加して、SSL圧縮が起きればそのバイトが秘密情報に含まれる事が分かる。これを繰り返して、秘密情報全体を決定していく。
http://www.scutum.jp/information/waf_tech_blog/2012/09/waf-blog-014.html

攻撃に必要なたくさんのHTTPSリクエストを発生させるには、別個にブラウザやそのプラグインの脆弱性などを必要とする。(追記:原理的にはscriptタグなどで外部ドメインから直接叩く、というのはアリそうだけど、正しく外部呼び出しがコントロールされたHTTPSサーバーなら回避できるはず)つまり、javascriptやRefreshなどの悪意あるリクエストを生成するコードをブラウザに注入できるものの、クッキーのhttpsonlyなどによって、スクリプトだけでは秘密情報を取得できない場合を対象にしている。
また、囮無線LANアクセスポイントなど、パケットキャプチャ(少なくともパケットのサイズやタイミングの推定)が容易にできることも前提になる。

提案されている攻撃では、バイトシフトや圧縮を利用して最大256通り・平均128通りのリクエストを試すことで、1バイトの秘密情報を奪うことが出来る。実際にはCookieなどの秘密情報はBase64やhexで書かれている事が多いので、最悪だと平均8回で4bitの情報が漏れることになる。
秘密情報がSHA-1 160bitのhexなら、わずか320クエリ程度で完全に特定できるので、単純にリクエストの頻度によってサーバーサイドでフィルタする方法では、ブロックする閾値が低すぎて通常利用に差し支えるだろう。


サーバー側HTTPSプロトコルでの対応
対処法としては、HTTPSサーバーの設定で、CBCモード暗号を使わず、SSL圧縮を無効にすれば、今知られている手法に対しては一応対応できる。ただし、圧縮やタイミングをサイドチャネル攻撃は様々なレイヤー・状況下で発生するので、完全に防ぐのは無理かもしれない。対症療法的に、暗号にCBCを使わないRC4を使うというものもあるが、それは暗号強度の面で問題が有る。
http://tetsutalow.hateblo.jp/entry/2013/04/02/053927


サーバー側アプリケーションでの対応
一方、アプリケーションレベルでCRIMEを含む圧縮率やタイミングによるサイドチャネル攻撃の排除方法としては、秘密情報を毎回変化させてしまう、という方法が挙げられる。
これらの攻撃手法は、秘密情報が少しずつ漏れるという特徴があるので、クライアントに保存するログイン情報を、毎回サーバー側で自動生成してしまう。
ただし、Cookie送信自体はクライアント側だけでパイプラインして複数回行えるので、リクエストとレスポンス到達の時間差によっては、サーバーが攻撃を検知してクッキーを再設定する前に攻撃を終わらせられるような改良手法が出てくるかもしれない。


クライアント側HTTPSでの対応
CBCモードでTLS1.0がIVを使いまわす事を利用したBEAST攻撃は、接続の切断や無効なリクエストの付加でIVを定期的にリフレッシュすることで対処できる。また、SSL圧縮に対応させないことで、既知のCRIMEに対処できる。

SSL/TLS実装が改修されていない、あるいは密結合していないブラウザの場合、HTTPクライアント側で、ゴミデータをリクエストに追加するという方法も考えられる。

一つは、GETやPOSTに先行して /favicon.ico (ドキュメントルート)など へのHEADリクエストを挿入してしまう方法。
HEADリクエストは副作用が無いので、404でも200でも構わない。これでIVを挿入したリクエストの末尾の暗号ブロックにリフレッシュ出来る。

もう一つはランダムな内容とある長さの独自HTTPヘッダを秘密情報の前後に挿入すれば、バイト境界を利用するタイプの攻撃は排除できる 難しくなる。たとえば
X-NONCE-1: ランダム長さの乱数列
Cookie: xxxxx;
X-NONCE-2: ランダム長さの乱数列
というように、ブラウザがランダム長の乱数で秘密情報の位置をシフトしたり、圧縮辞書を変化させてやれば、攻撃したいバイト境界がリクエストの度に変化するので、攻撃を著しくある程度困難に出来る。(追記、ただバイトシフトするのではBEASTは1/可変長にしかならない。圧縮系には意味があるが)

ブラウザはどれが秘匿すべき情報なのかアプリケーションの詳細を知らないし、独自ヘッダではクエリ文字列にセッション情報を保持するようなアプリケーションには対処できない(ただjavascriptを注入された時点でクエリ文字列は取得されているはず)、といった問題はあるけれど、この手法はSSL実装をOSに依存した軽量なブラウザや、ブラウザの追加アドオンなどでできるので、BEAST等に脆弱だが改修できない古いHTTPSサーバーやクライアントライブラリに対して、ユーザーやブラウザアプリ開発者の対抗手段時間稼ぎとして利用できる。



サーバー側のopensslバージョンによる制限
クライアント側が完全に実装されるまで、現時点ではサーバー側で、TLS1.1以降やGCMモードなどのバイトシフトによる攻撃が難しいモードを使い、SSL圧縮を無効にするといった方法で対処することになる。
ところが、そのために必要なopensslは1.0.1以降で、まだ数の多いRHEL6.xではいまだ1.0.0のため、互換性を捨てて1.0.1以降にするか、TLS1.0のRC4しか回避する手段がない。そしてRC4にもまた脆弱性が見つかっている。

1.0.1以降が入っているなら、TLS1.1以降を有効にしているクライアントに対しては、RC4のような古い暗号を優先せず、AES-GCMなどを用いるべき。


秘密情報のないサービス
これらの攻撃は秘密通信をリークするだけなので、秘密情報を扱わないアプリケーションには影響しない。
フリーソフトウェアの静的な配布サイトのように、誰でも匿名でダウンロード出来る情報しかないウェブサイトなら、漏れて困る情報はない。
HTTPSでダウンロードした内容やHTTPSのウェブサイトに記載されたソフトウェアの証明書フィンガープリントが改ざんされている、ということは上記の手法では考えにくい。

結局自分のアプリ配布用サーバーはRC4ということで妥協しておく。

nginx設定メモ
    ssl_prefer_server_ciphers on;
    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;  #実際にはTLSv1.1以降使えていない
    ssl_ciphers  AESGCM:RC4:HIGH:!MD5:!aNULL; #RC4以降しか使えていない
    # AESGCMと省略出来る事に気づいたので変更

SSLチェック https://sslcheck.globalsign.com/ja/sslcheck?host=app.usb0.net
ラベル:Beast crime CentOS
posted by ko-zu at 11:05| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2013年08月08日

オンラインサービスパスワードとストレージのパスワードと端末ログインパスワードの違い

徳丸氏による徳丸氏への取材ブログ「パスワードの定期的変更について徳丸さんに聞いてみた」
(1) http://blog.tokumaru.org/2013/08/1.html
(2) http://blog.tokumaru.org/2013/08/2.html
前後の反応を見ていて、オンラインサービスのパスワードの話と、ストレージのパスワードや端末のログインパスワードの話が混同されていることが多いように思われた。
どれもパスワードと呼ばれることがあるが、必要な強度や性質の違いに留意していれば、/etc/passwdやNTログインキャッシュと、オンラインサービスのパスワードの話が同列に語られるはずがない。


オンラインサービスのパスワード
=短期間総当りされない程度に強い鍵を使う

・サービス側が攻撃を検知できるので、攻撃者がサービスへの侵入なしに総当りするのは事実上不可能
・通信経路はずっと強い鍵で暗号化されているので、盗聴は考えなくていい(HTTPSでないウェブサービスは、あなたの安全のためではなく、最も簡単な個人識別方法としてパスワードを用いているだけ)
・サービス側からの漏洩が起きる確率は、ユーザーがパスワードを変えても変化しない
・生のパスワードが漏れた場合、実際の攻撃に利用されていないなどあり得ないので、パスワードを後から変えても意味が無い
・パスワードのセキュアなハッシュが漏れても、少なくとも数日〜数ヶ月はパスワードが逆算されることはない
・ハッシュが漏れたことに直ちに気づかないサービスが、保護するべき情報が漏れていないことを保証できると考えるべきではない

→ 12〜20文字程度(だいたい70~120bitくらい)のパスワードをランダム生成して、ブラウザなどに保存する。もしハッシュが漏れたとニュースがあれば、即座に変更する
→ 端末の紛失、フィッシングや、野良アクセスポイントの利用など、ユーザー側責任での漏洩に注意する


通信・ストレージの暗号化パスワード
=盗聴されることを前提にした、長期間総当り不能なとても強い鍵を使う

・攻撃者は盗んだ暗号文を保存して秘密裏に総当りできるので、十分な強度が必要
・「鍵と暗号方式の耐久年数」- 「情報が価値を持つ期間」 = 「同じ鍵を使っていい期間」 なので、新しいデータのための鍵を定期的に変えることには意味がある
・古い鍵で暗号化したストレージを、そのまま新しい鍵で暗号化し直すことは意味が無く、しばしばより脆弱になる(古い暗号文が絶対に漏れていないことを保証できるなら別だが、それなら暗号化の必要がない)
・通信や大容量データ暗号化ならAES-GCMの128bit以上が推奨 http://www.cryptrec.go.jp/images/cryptrec_ciphers_list_2013.pdf

→ 最新のブラウザを利用する。ただし紛らわしいドメイン名でのフィッシングには注意が必要
→ TrueCryptなどのデータ暗号化ソフトは短すぎる鍵を警告してくれる(警告がでない暗号化ソフトは見せかけだけで、正しく暗号化してない可能性が高い)


ブラウザのマスターパスワード、PCのログインパスワード、スマートフォン端末のPINコード
=弱い鍵と物理的にアクセスさせないことの組み合わせ

・パスワードと呼ばれるが、実体はログインユーザーの秘密情報を暗号化するための鍵
・通常入力できるパスワード・PINだけでは鍵として弱すぎるので、物理的にアクセス出来ない状況という前提を組み合わせて擬似的に強度を高めている
・暗号文=端末そのものが盗まれれば簡単に総当りできるので、盗まれない対策が必要
・保護したいデータはほどんど変化せず、IDや個人情報のように後から変更できないものが多いので、端末を紛失したら暗号文が漏れないように、リモート削除する
・暗号文は漏れていない(端末は盗まれていない)ことがわかっているが、盗み見などでパスワードだけ漏れた場合がありうるので、パスワードを定期的に変えることは意味がある

→ 最新のOSとブラウザとセキュリティソフトを利用し、端末のストレージから暗号文が盗まれないよう注意する
→ リモート削除機能を用意して、紛失に気づいたら即座に削除する(=バックアップする)
→ リモート削除できない携帯用のメディアやノートPCは、TrueCryptなどでストレージを暗号化して、強いパスワード(20文字で約120bit)を利用する


漏洩に気づかない場合
ユーザーの不注意などでパスワードが漏れたのに、そのユーザーが気づかないかもしれない、だから、パスワードは変えたほうがいい、ということは有りうる。しかし、漏れる頻度よりずっと高い頻度でパスワードを変えないと意味がない
端末のパスワードでは端末そのものを入手できないとパスワードを悪用できないが、オンラインサービスへは誰でも匿名でアクセス出来てしまう。オンラインサービスへの攻撃は自動化されているので、ほとんど一瞬にしてパスワードで保護されていた全情報が漏洩してしまう。

高頻度のパスワード変更を人力でやるのは不可能なので、トークンによって自動生成されるワンタイムパスワードなどが利用されている。トークンの中には電子証明書が入っていて、人間が入力できるパスワードよりずっと強度が高い。それがたった6桁の数字に見えたとしても。


結局、
・オンラインサービスでは、安全な暗号通信で利用しているなら定期的にパスワードを変える利点は無い(ワンタイムパスワードは例外)
・物理的なストレージや端末のパスワード・PINコードは、可能な限り強くし、定期的にパスワードを変えることには意味がある
・利便性のために弱いパスワードしか使えない端末は、紛失時のためのリモート削除機能を利用する
ラベル:暗号論
posted by ko-zu at 21:38| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2013年03月13日

JCBのクレジットカード情報を第三者が取得できる可能性

JCBがカード会員向けウェブサイトMyJCBにおいて、rt.rtoaster.jpのjavascriptを読み込んでいたので煽り気味に。面倒なことに埋め込まれているのはログイン後ページなので、魚拓などがとれなかった。Webの人はここまで読めばもう意味が分かるだろう。


サードパーティのjavascirptをウェブページに埋め込むことは、アクセス解析・ユーザー追跡や広告の挿入のために普通に行われている。このseesaaブログでも、google analyticsといったアクセス解析ツールや、広告業者のドメインでホストされているjavascriptを多数読み込んでいる。jQueryなどの基本ライブラリもgoogleやMicrosoftの提供するCDNから利用しているウェブサイトは多い。

scriptタグでウェブページに直接読み込まれたスクリプトは、読み込みウェブサイトと同じ権限を持つ。つまり、(httponlyでない)クッキーの読み書きや、フォーム内容の読み書き、同一ドメインへのリクエストの発行など、javascriptで可能なあらゆることが行える。他社が提供するスクリプトをウェブサイトに埋め込むということは、『ユーザーがアクセス・入力しうる全ての情報や機能』へのアクセス権限をブラウザ経由で第三者に提供することに等しい。
そして、ウェブサイトのオーナーが指定できるのは外部スクリプトのURLだけであって、その内容は外部スクリプトを提供する側が自由に変更できてしまう。導入当初はウェブサイトオーナーの意図した通りのスクリプトでも、ある日からXSS攻撃用の悪意あるスクリプトに変化するということは十分に起こりうる。XSSが可能になれば、"本物のドメイン"上でパスワード入力フォームを偽装することだって出来る。これが重要な情報を扱うウェブサイトやその同一ドメイン内に、第三者のスクリプトを埋め込んではならない理由だ。


MyJCBの場合、例えばログイン直後の画面でユーザー追跡用のjavascriptとしてrt.rtoaster.jpのスクリプトを読み込んでいるため、クレジットカード利用履歴ページをバックグラウンドで読み込むことが出来る。フォームを偽装すればMyJCBで入力する可能性があるオンライン取引用のパスワードなどを得ることも出来るだろう。
もちろん今現在漏洩が起こっているというわけではないが、悪意をもってrt.rtoaster.jp内のスクリプトを書き換えられれば、MyJCBで得られる情報やMyJCBにユーザーが入力しうるIDやパスワード・個人情報は全て漏洩しうる。

JCBが情報漏洩対策として自社サーバにおいて、どんなに厳重なセキュリティを保っていても、外部スクリプト配信サーバーのセキュリティが甘ければ、実質的にJCBのサーバー内の情報にアクセス出来てしまう。つまり、外部スクリプトの配信サーバーには、自社の配信サーバーと同等以上のセキュリティが要求される。意地の悪い言い方をすれば、MyJCBではhttps://my.jcb.co.jp/のサーバーのセキュリティ要件としてrt.rtoaster.jpと同等かそれ以下の甘い要件しか課していない、ということになる。

さらに意地の悪い考え方をすれば、外部スクリプト提供側やその末端のサーバーオペレータが悪意をもった場合、スクリプトを書き換えることで秘密裏にMyJCB内のデータを収集したり、パスワードやIDをフィッシングすることさえ出来てしまう。外部スクリプトはブラウザが直接配信サーバーから取得するため、MyJCBサイト側は内容を検査することはできない。JCBはスクリプトが意図に反して改変されていないかチェックしているかも知れないが、ABテストのようにごく一部の一般ユーザーだけをターゲットにするなど、バレにくくする方法もある。

外部スクリプトを用いず、アクセス解析や広告配信システム自体を購入して、同一ドメイン内の自社サーバーから配信すれば、第三者にブラウザ経由で情報が渡るリスクは生じない。実際のオペレータとして第三者に業務委託することになるかもしれないが、少なくとも、自社の他のサーバーと同じセキュリティの元で配信システムを管理する事ができる。

JCBは外部スクリプトをMyJCB内に埋め込む方法を選んで、自社で運用するよりも安価にサービスを得られたかもしれないが、第三者のサーバ経由で情報が漏洩するリスクを犯している。
サードパーティのスクリプトを埋め込む手法は便利だが、ユーザーがアクセス・入力しうる情報に重要なものが含まれていないか、十分に吟味した上で行うべきだ。
ラベル:セキュリティ
posted by ko-zu at 23:33| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2013年02月05日

第三者のDNSリゾルバを使う場合の問題について

自作のAndroidアプリに関連して、パブリックDNSリゾルバに関する誤解と思しき内容を見かけたので書いておく。


DNSリゾルバ(主にインターネット端末がドメイン名から接続先サーバのIPアドレスを調べるためのサーバ)の中には、誰でも自由に利用できるオープンリゾルバ・パブリックリゾルバと呼ばれる物がある。アドレスが8.8.8.8と覚えやすいGoogle Public DNSが著名だ。(日本では次点でNTT Americaか)
DNSで配信される情報は基本的に公開かつ普遍的(誰が調べても同じ)な内容なので、誰がリゾルバを提供してもプロトコルとしては問題ないのだが、第三者の提供するリゾルバを使うという事をプライバシー上問題視する意見が有る。

まず、(第三者の)DNSリゾルバを利用することにはプライバシー面で問題が発生する可能性がある、ということは事実だ。

DNSサーバーへのアクセスログを収集すればIPアドレス単位でユーザーがどのようなウェブサイトにアクセスしたか、どんなオンラインサービスを利用したかというアクティビティを推定することが出来る。
例えば、SNSの個人情報に紐ついたブラウザでアクセスした時、同一端末のIPアドレスから来たDNS問い合わせのドメインを収集し、個人情報と紐つけることは法的にはともかく技術的には容易だ。今後(プライバシー面で)杜撰なIPv6実装や運用が普及すれば個人追跡はさらに容易になるだろう。
グーグルを始めとする商業的に提供される無償のDNSリゾルバは、IPアドレスと紐付けられたユーザーの情報を欲しいがために高性能なDNSを提供して利用者を増やしている、と自分は考えている。
電気通信関連の法令の管理下となるISPの場合、ユーザーの情報を通信内容から収集することは制限されている。DNSリゾルバとのやり取りではISPが通信当事者になるので、DNSリゾルバのログは必ずしも通信の秘密として保護されるわけではないが、無関係な第三者よりはプライバシーを意識して取り扱われることが期待できる。もちろん、ISPにさえ通信内容を秘密にしたいのであれば、Torrなどの匿名化手法を使うしかないので、自身のウェブアクティビティをどこまで提供してよいか、という程度の問題といえる。


一方、DNSリゾルバから得られる内容の正確性については、どのDNSリゾルバを使おうと基本的に改竄されるリスクがあることに違いがない

まず、DNSにはDNSSECという情報の正当性を保証する機構があるものの、まだ一般には普及していないため、DNSSECで正しいと保証できない場合においても必ずしも内容が無効になるわけではない。ユーザーが明示的に検証を行うためのソフトを導入しない限りは、DNSで得られた内容が正しいかを検証することは出来ない。

現状のインターネットでは、DNSで得られた情報が正しいかどうかは一旦保留し、DNSで得たアドレスのサーバに通信を試みて、本当に目的のサーバーか確認することで安全を確保している。これはSSLやTLSとよばれる暗号通信と接続先認証プロトコルを用いて実装されていて、インターネットで一般的かつ根本的な解決法とされている。
これらの通信プロトコルで暗号通信し、かつ通信対象の証明書が権威の有る認証局から発行されたものか検証すると、通信対象が『接続したいドメイン名を名乗ることが認証局に許された正当なサーバーである』ことが保証できる。
(証明書を検証せずただ暗号化しただけでは、中間者攻撃=悪意ある伝言ゲームをすれば回避できてしまう。またいわゆるオレオレ証明書ではドメイン名を名乗る正当性は証明できない)

DNSから得られた情報が仮に誤っていたとしても、証明書を検証すれば接続が遮断されるので、情報が漏れたりすることはない。また、ドメインの所有者が管理しているDNSサーバーや、ドメインレストラのアカウントが侵入されるなどして、DNSプロトコルとしては正しいが、結果として悪意ある情報が混入された場合も、証明書を検証すれば接続できないという以上の問題はない。

また、DNSというプロトコルは正常に運用されている状態でも、歴史的な性善説的実装や性能面を理由に、様々な悪意ある情報の混入が起こりうる。(だからこそ常にHTTPSが必要)
攻撃対象のドメイン名に対応するIPアドレスを不正に上書きするDNSポイゾニング攻撃では、現状の(DNSSEC有効でない)DNSの原理上、成功確率を下げることはできても完全に排除することが難しい。また、近頃数多くのTLD管理下のDNSサーバの内容が不正に改ざんされるなど、DNS運用者側のセキュリティ上の問題も皆無とはいえない。
DNSにたよるシステムでは、もっと言えばインターネットというシステムでは、確実に接続できるという保証は存在しない

結局、DNSリゾルバが返す内容が正しいかどうか、安定性(接続できなくなることがない)や性能(どれぐらい高速か)という点では意味があるが、DNSの内容が正しくても、最終的な通信経路(例えばWiFi無線など)が安全でない場合、接続先サーバーのアドレスが正しくても何の意味もない
DNSで得られた情報に高い信頼性を求めることよりも、SSL/TLSによる暗号化通信でエンドツーエンドの安全性を検証することこそが重要ということだ。


次にフィルタリングによる意図的な編集が考えられる。

現在のDNSでは、リゾルバを提供する管理者が、DNSで配信される情報に意図的に手を加える事が許容されている。
例えば、明らかに犯罪に利用されている場合など、ドメイン運用上のルールに反したドメイン名を無効にする、といったことがDNSリゾルバの段階で行われている事がある。これを一歩すすめたものが、自分が提供している広告フィルタDNSだ。
こういった手法はDNSフィルタリングと呼ばれ、不正ドメイン対応だけでなく、不正なIPアドレスや実際には利用できないAAAAレコード(IPv6アドレス)など、セキュリティ改善や端末の接続性改善などの様々な目的でISPを含め多くのDNSリゾルバに適用されている。このフォルタリングポリシーやフィルタ内容の全容を公開しているISPは、そう多くないだろう。少なくとも自分は知らない。
フィルタリングによって内容が変化している可能性は常に存在し、リゾルバ管理者による不適切な改竄が気になるのであれば、自分自身で完全なリゾルバを用意するしかない。


どのDNSリゾルバを利用するかは、
・管理者に自分のネットでのアクティビティ情報を渡してよいか?
・DNSリゾルバのフィルタリングポリシーは適切か?
・DNSリゾルバの性能は十分か?
を勘案して決めるべきということになる。

拙作の広告フィルタDNSや、アンチウイルスベンダーの提供するセキュリティフィルタDNSなどを利用することは、個人的には考慮に値する選択肢であると思う。
(ユーザー行動監視なんてブラウザからSNSからポイントカードから収集されすぎていて慣れっこだ、という現代人には特に)

繰り返すが、どのDNSリゾルバを利用するにせよ、暗号通信と証明書による接続先の検証は非常に重要だ

ウェブブラウザではユーザーにHTTPSの利用を強制する仕組みが整いつつあるものの、まだ完全ではない。IMAP・POP・SMTP・FTPなど比較的マイナーなプロトコルは言わずもがな。
あなたにとって価値がある情報を取り扱うネットサービスにおいて、暗号化通信が提供されていなかったり、証明書が正しく設定されていなかった場合は、直ちに代替のサービスを探すことをおすすめする。
posted by ko-zu at 18:32| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2012年12月18日

DNSSEC非対応キャッシュサーバを通した改竄の検証とBINDの挙動

dnssec-enable no;でのBINDの挙動についてメモを兼ねて。

DNSSECではRRSIGリソースレコードに
・署名対象の名前
・署名対象のリソースタイプ・クラス
・署名対象のオリジナルの(コンテンツサーバでの)TTL
・RRSIG自体の有効期間、鍵のハッシュなど
を載せ、電子署名で保護している。

RRレコードと、対応するRRSIGレコードを受け取る事ができ、対応する公開鍵を信頼しているならば、
「現在時刻と照らしあわせてRRSIGレコードが有効期間内である事」を確認し、さらに、「Aレコードの元々のTTLがRRSIGの主張するオリジナルTTLだったと仮定して、現在時刻と照らしあわせて署名に矛盾がない」ことを確認することで、改竄されていないことが証明できる。
(公開鍵はルートから権威の木構造で証明するが署名原理は同じなので割愛。NSECも割愛)

キャッシュサーバから受け取るRRSIGレコードのTTLは、時間経過にともなって減少しているが、RRSIGには元のTTLが明記されているので、無矛盾を確認できる、したがって、キャッシュサーバが全てのレコードをフィルタすることなく(TTL以外変化させずに)透過的に返答してくれるなら、経路上のキャッシュサーバがDNSSEC検証していなくても、検証は可能になる。

例えば、あるQNAMEでQTYPE=Aで問い合わせしてAレコードしか得られなかった場合、QTYPE=RRSIGレコードで問い合わせすればRRSIGレコードが全て得られるはずなので、その中から必要なQTYPE(ここではA)に対応するRRSIGレコードで検証を行えばいい。


BINDの実装では、この手続を行うクライアントで問題が生じる。

前提として、DNSプロトコルのEDNS0という拡張に更にオプションで、DOビットというフラグがあり、DNSSEC対応しているクライアント(リゾルバ側)はこれをセットしてクエリすることで、サーバー側はQTYPEに対応するRRSIGレコードを追加で返すことになっている。

BINDは再帰問い合わせを許容する場合、オプションで
 dnssec-enable no;
 と設定すると、DOビットをセットしたクエリに対しても、RRSIGを付加しない。
一方、dnssec-enable noにもかかわらず、応答のために外部に問い合わせる際にはDOビットをセットして問合せ、RRSIGなどのDNSSEC用レコードが付加されていればキャッシュする。

このサーバーに対して、QTYPE=RRSIGとしてDNSSEC対応クライアントが問い合わせると、BINDは一部のRRSIGだけ返してしまうようだ。
たとえば同じQNAMEにAレコードとTXTレコードがあり、TXTレコード用のRRSIGレコードだけがキャッシュに有った場合、Aレコードを検証したいクライアントはRRSIGでクエリしても必要なRRSIGレコードが得られない。

通常DNSキャッシュサーバからのレスポンスでは、NAME・TYPEが一致するレコードは全てTTLが一致し、キャッシュ上のデータは全か無かしかない。例えば本来3つあるNSレコードのうち、1つしかキャッシュに残っていない、ということは少なくともDNSSECの署名においては想定されていない。(権威サーバの設定でTTLがそもそも違う場合、同時に対応するRRSIG署名も消えるはずなので良いが、同じTTLのレコードが一つだけ消えたりした場合検証失敗してしまう。これはDNSポイゾニングを想定した動作)
現在のBIND9.9.2の実装では、付随的に受け取った部分的なRRSIGレコードをキャッシュしてしまうため、QTYPE=RRSIGなクエリに対して、部分的なRRSIGレコードを返してしまう。バリデータはTTLが異なる他のTYPE用のRRSIG RRから、必要なTYPE用のRRSIG RRがあるかもしれないことを検出できるが、BINDのキャッシュを外から制御できるわけではないので他の経路を探す必要がある。

BINDのこの(恐らく不正な)挙動がなければ、DNSSEC非対応キャッシュサーバを経由してもDNSSECは機能するはずであり、『DNSSECはキャッシュサーバが対応しないと利用できない』というのはBINDの実装を前提とした問題とおもわれる。

指摘頂いて最初、RRSIGは部分的な応答が許される特殊なレコードなのでRRSIGクエリは禁止されているのか思っていたが、RRSIG自体は普通のRRであって、digなども+nodnssecであってもRRSIGクエリタイプを認識する。DNSSEC以前の古いキャッシュサーバを透過するためにもそう有るべきだ。

BIND側はdnssec-enable no;な場合再帰問い合わせでDOフラグをがセットするべきではないし、DOフラグによって付加的に得られた、部分的なRRSIGレコードはキャッシュするべきでない。
少なくとも、QTYPE=RRSIGのクエリに対しては、改めて問い合わせするよう実装しなければならないはず。

このへんはRFC読みなおすことにする。


追記

例えばCDビットセットかつDOビットがセットされtruncatedでないNOERRORなレスポンスにRRSIG RRが付いていなければ、RRSIGが存在しないと分かる。一方、問い合わせ先がDNSSEC非対応だった場合、DOビットは単に無視されるのでNOERRORでRRが見つかり、RRSIGは返されないが、RRSIGが存在しないのかは不明になってしまう。この場合、バリデータ側はRRSIGが無かったとネガティブキャッシュし検証失敗と判断するべきか、あるいは他の方法を試して良いのか?

個人的には否定応答ではないのだから、キャッシュしないほうが正しいと思う。少なくとも、明示的にネガティブキャッシュするべきとは書いていないし、「バリデータは同じレスポンスメッセージに含まれるRRSIGしか検証に利用してはいけない」といった類の要件も見つけられなかった。とすると、賢いバリデータはDNSSEC非対応な経路を検出してDOフラグ拡張を使わず明示的にクエリしたり、他のキャッシュサーバを試したりするようなフォールバック動作をするかもしれない。

RRSIGはそのRRSIGレコード自体の有効性をも検証できる(でなければ意味が無い)ので、最初のQTYPE≠RRSIGなクエリでえた目的とするTYPEと、他の経路で得られたRRSIGを組み合わせて検証することが出来る。
ラベル:DNS DNSSEC
posted by ko-zu at 00:36| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2012年12月15日

SipHashとAdvanced Hash Flooding

https://twitter.com/a4lg/status/279543990972461056
http://crypto.junod.info/2012/12/13/hash-dos-and-btrfs/
あたり経由でカーネルのBtrfs実装に関するHashDoSの話。を経由して
SipHash https://www.131002.net/siphash/
 について流し読みした。何故暗号論的ハッシュが必要か指摘していたのでめも。

SipHashは、HashDoS耐性のある高速ハッシュアルゴリズムとして使える暗号論的擬似乱数生成器。

高速性は主に、
・128bitの生成鍵(salt相当)からコストの大きな拡張関数を使わずそのまま初期状態を作れる。
・ブロックは64bit単位と小さく、状態空間は64bitx4
・ルックアップテーブルを使わない
あたりで実現されていて、
一方で暗号論的に安全なハッシュアルゴリズムを取り入れつつ
・ラウンド数は可変だがSipHash-2-4以上なら鍵の推測が難しい
・決定論的に一定時間で計算が出来る。CPUのALU実装に問題が無ければタイミング型サイドチャネル攻撃に頑強。
その他暗号論的ハッシュとして基本的な強度検討はなされているっぽい。

他にもハッシュテーブル実装目的のハッシュアルゴリズムはCityHashなどがあるが、暗号論的な一方向性はもたない。例えばCityHashでは一様性が低いらしく、攻撃者が外部から鍵(salt)を推測してHashDoSを引き起こせる可能性がある。


Advanced Hash Flooding (論文内の表現)
タイミング攻撃が可能なら暗号論的一方向性をもたないハッシュでは鍵が一定である限りHashDoSは容易という話。
まず、ハッシュテーブルを使うならタイミング攻撃、すなわち、コリジョンが起きたとき処理が少し遅くなることを検出するサイドチャネル攻撃が通用することは避けられない。

ハッシュに一方向性のない、または弱い場合では、タイミング攻撃でコリジョンが発生するペアが幾つか分かってしまえば、鍵を推測してコリジョンを起こす他のメッセージを大量生成できてしまう。
CGIなど、プロセス立ち上げの度に鍵を更新できるならいいが、寿命の長いデーモンで鍵が更新されるまでにタイミング攻撃が出来るなら、ハッシュ関数に鍵をつかっていようとHashDoSに脆弱になる。

暗号論的な一方向性があるならば、メッセージがコリジョンしたかどうかという情報から鍵を推測することは出来ないので、コリジョンが見つかったからといって、攻撃者は衝突する異なるメッセージを作成することはできない。攻撃者はコリジョンを一つずつタイミング攻撃で調べていく必要があるので、hashdosの準備がとても困難になる。大きなオンメモリデータベースなど、鍵を容易には更新できない状況下でも、hashdosへの対策としては十分になる。
というわけでSipHashでは一方向性が高いハッシュ関数を使うことを推奨している。

SipHashは強度がそこそこあり、短いメッセージに対しても性能がリニアで、短いキーを扱うことが多いインタプリタ実装のハッシュテーブルにも適しているとしている。
posted by ko-zu at 09:10| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2012年12月12日

セッション管理ポリシーとフィクセーション

徳丸浩氏と大垣靖男氏の間でセッションフィクセーションに関するやり取りが有ったが、恐らくこれはセッション管理ポリシーの食い違いと思えたのでまとめてみる。
http://tumblr.tokumaru.org/post/37676352092/session-adoption-and-session-fixation
http://blog.ohgaki.net/session-adoption-and-session-fixation-and-session-hijack

自分の理解では、
徳丸氏は「権限昇格時のセッションIDの再生成でセッションフィクセーションによるハイジャックは排除できる」
大垣氏は「アダプション対策はハイジャック対策に必須」
と主張されているように見える。恐らくこれはセッションID発行に関する管理ポリシーの違いに起因する。

共通の前提として、攻撃者はサブドメインへのクッキーなど、サーバー内の実装や脆弱性に依存しない方法でフィクセーションを起こせるものとして、フィクセーションが不正な権限昇格に繋がるかを考える。
バックエンドサーバー・DBへの不正アクセスやXSSやCSRFなど、フィクセーション以外のサービス側の問題は考慮しない。また、誤った乱数実装や善良なユーザーからのセッションIDの漏洩によるハイジャックも別件として考慮しない。セッションID管理はCookieベースとする。


徳丸氏の前提としたポリシーは恐らく、
・全く権限のない匿名のユーザにもセッションIDを発行する
・権限昇格時にセッションIDを再生成する
攻撃者は容易にセッションIDを生成出来るので(Torなどで匿名アクセスしてCookieを貰えばいい)フィクセーションは起こせるが、昇格した権限は新しいIDに紐つくため、被害ユーザーはCookie重複によるログイン不能などDoSに晒されるものの、攻撃者が権限昇格することはない。なお、Cookieのキーもランダム化するなどでDoSの軽減は可能である。
再生成しないと、フィクセーションで権限昇格可能な深刻な脆弱性になる。

大垣氏の前提としたポリシーは恐らく、
・権限取得時に有効なセッションIDを発行する(=信頼できない攻撃者はセッションIDを取得できない)
・権限の変更や昇格の際は再生成し、破棄時にはセッションIDも無効化する(=セッションIDの有無と権限の有無が一致する)
と推測した。
サービスにログインできない攻撃者はフィクセーションを起こそうとしても、アダプション対策を回避できる有効なセッションIDを知らないので、フィクセーションは成功しない。逆に言えば、アダプション可能だった場合セッション管理フレームワークの深刻な脆弱性になる。

なお、どちらのポリシーでもログイン済みユーザーはフィクセーションは起こせるので、ログイン可能なユーザーに攻撃者がいた場合に備えて、ユーザーに”サーバーが認識しているユーザー名”を確認してもらう必要がなる。

このように前提が異なると仮定すると、両者の言っていることはどちらもそれぞれの前提の元で正しいように思われる。

前者のポリシーでは、セッションIDの有無は重要ではないので、アダプション対策の意義は攻撃検出などに限られる。一方、後者のポリシーではログイン状態の判定を、セッションIDの有無に依存しているため、セッションIDが捏造されたものか判定するアダプション対策は重要になる。

後者のポリシーでも権限昇格の際はセッションIDを再生成するか、権限を一時的なものとして(suではなくsudoのように)その都度PINを入力する方式にする必要がある。例えば、ログインユーザーが特権ユーザーに昇格する場合など、もし同一のセッションIDのまま権限昇格が可能なら、弱い権限を持つ攻撃者は弱い権限のセッションIDを取得して、強い権限をもつユーザーにフィクセーションを仕掛けることで権限昇格可能なハイジャックに相当する。


結局、regenerationは権限昇格時に必須だが、ログイン状態と有効なセッションIDの有無を対応付ける実装をする場合にはアダプション対策"も"必須、ということと思われる。

個人的にCookieとログイン状態の暗黙の対応関係に依存するのはプログラミング的には筋が悪いと感じられる。しかし、セッション管理と広告などを目的としたユーザー追跡が完全に分離されるので、ユーザー視点ではプライバシー上後者の方が好ましい。もっとも、その場合別の追跡クッキーが発行されるのでそちらはブロックする必要があるだろうが。

自分の理解した範囲の結論としては、どちらのポリシーにせよ、IDの再生成をすれば権限昇格タイプのセッションハイジャックは回避できる。フィクセーションは可能なら潰すべきだが、サブドメインベースの共用ホスティングを使うユーザーもいるので、プログラマーのレベルでは完全に潰すことは難しく、ログイン出来る攻撃者からのフィクセーションが成功しても致命的な問題が起こらないように、ユーザーにユーザー名を常時表示するなど、十分注意して実装しなければならない。アダプション対策は後者のポリシーで、セッションIDの有無に依存する実装の場合にのみ注意すればよい。

勝手な推測でセッション管理ポリシーを推定したが、これ以外のポリシーでは、アダプション対策でにフィクセーションによるハイジャックを回避できるシナリオが想定できなかった。
posted by ko-zu at 06:30| Comment(2) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする

2012年11月14日

オープンDNSリゾルバのDoS対策メモ

「Android/iPhoneスマホのroot不要な広告除去法」http://causeless.seesaa.net/article/289244107.html
で書いたように自宅サーバで、広告避けオープンDNSリゾルバを運用しているが、DoS攻撃と思われるクエリがよく来ている。

ほとんどがripe.netやisc.orgへのANYクエリで、特定のソースIPから短時間に多量の連続したアクセスがある。偽装されたソースIPへのトラフィック集中を目的としているらしく、DNS Ampによる回線飽和DDoS攻撃が実行中と思われる。

自分の回線やサーバーへの負荷は大したことは無いが、DoSの片棒を担がされているのは気に入らないのでフィルタ方法を考えてみた。


REFUSEする
自分のリゾルバは広告除去目的の限定的なオープンリゾルバなので、今回利用されたドメインへのクエリを一時的に禁止してみる。
zone "ripe.net" IN {
type master;
file "block.db;
allow-query {none;};
};
DNSリゾルバにセカンダリを正しく設定してあればそっちに問い合わせするので問題ない。高々最初のアクセスのレスポンスが1秒ほど遅くなるだけ。


REFUSEDをドロップする
BIND9にはunboundのdenyに相当する設定が無いので、refusedを返さず無視することが出来ない。仕方ないのでiptablesルールで何とかする。
コードが5=REFUSEDなレスポンスをDROPするルールを追記して対応
-A OUTPUT -p udp -m udp --sport 53 -m u32 --u32 "0>>22&0x3C@8&0x0F=5" -j DROP


hashlimitをかける
上の2つで弾けているはずが、なかなかDoSのクエリがとまらなかったので、テストを兼ねてhashlimitルールでINPUT側をフィルタしてみた

-A INPUT -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT
だったものを
-N DNSCHECKIN
-A INPUT -p udp -m udp --dport 53 -m state --state NEW -j DNSCHECKIN
-A INPUT -p tcp -m tcp --dport 53 -m state --state NEW -j DNSCHECKIN
-A DNSCHECKIN -m hashlimit --hashlimit-upto 1/s --hashlimit-burst 50 --hashlimit-mode srcip --hashlimit-name DNSDENY --hashlimit-htable-expire 300000 -j ACCEPT
-A DNSCHECKIN -j DROP
に置き換え。これでほとんどDROPできた。
最初に50クエリまで許可して、以後1クエリ/sに制限。リゾルバのキャッシュが正しく効いてる普通のユーザーなら問題は無いはず。NATで複数人が回線共有していた場合残念なことになるが、そもそんな状況の人はオープンリゾルバ使わないだろうから「NATの中の人などいない」と割り切る。
(3G回線の人ならroot化済みでhostsでブロックしてるだろうし)


ということで対策してみた広告除去用オープンリゾルバ。101.111.213.2
セカンダリにはGoogle提供の8.8.8.8あたりをどうぞ。
公開停止しました。

posted by ko-zu at 20:28| Comment(0) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする