サーバーが特定の条件に基づいて行動するという仮定の下で、この条件の結果に応じてサーバーが計算を行い、次にユーザーに応答を返す状況を分析してみましょう。いずれの場合も、計算が行われるかどうかにかかわらず、サーバーはユーザーに応答を返します。注目すべきは、サーバーが計算を行う場合、特定のリソースを消費し、それによってサーバーの応答時間が長くなることです。通常、これらの応答時間の違いは極めて小さいため、最終ユーザーにはほとんど認識されません。しかし、これらの微妙な応答時間の違いが明らかになると、意図しないデータ漏洩を引き起こす可能性があります。
次に、この状況の実際の例を検討してみましょう。これはアプリケーションへのログインプロセスに基づいています。入力されたログインが正しいがパスワードが間違っている場合を想定します。この場合、サーバーはパスワードの検証などの計算を行う決定を下す可能性があります。サーバーがこれらの計算を行う場合、追加のリソースが必要になり、計算が行われない場合に比べて応答時間が長くなる可能性があります。応答時間の違いは通常小さいですが、攻撃者が測定することができる程度には存在します。
同じプロセスですが、ログインも間違っている場合:
応答時間のこのような微妙な違いの場合、攻撃者はこの情報を利用してログインの正確性を推測しようとする可能性があります。例えば、攻撃者は様々なログイン名を使用してサーバーの応答時間を分析する制限時間攻撃(timing attack)を実行することができます。応答時間を比較することで、どのクエリの時間がより長かったかを推測し、それがログインが正しいことを示唆します。ユーザーのログインが明らかになると、攻撃者はブルートフォース攻撃を実行してパスワードを推測することが可能になります。一部のケースでは、ログインが特定の人物に関連付けられたメールアドレスであり、試験対象のアプリケーションが論争の的になる内容を含むポータルである場合、機密情報が明らかになることも意味します。
Burp Suiteを使用したテスト – Request Timer
この種の脆弱性を探すときには、Request Timerという名前のBurpのプラグインが役立ちます。このプラグインは、指定されたリクエストに対するサーバーの応答時間を調査するのに役立ちます。
最初のステップは、ユーザーのログインに関連するリクエストをキャプチャし、それをIntruderモジュールに送信することです:
次に、パスワードを長い文字列に変更して、ハッシュ生成中にサーバーの負荷を増加させます。ユーザーのログインがある場所を指定します。調査対象のアプリケーションの場合、”X-Forwarded-For”ヘッダーを追加し、同じIPアドレスからの複数のログイン試行を回避するためにランダムなIPアドレスを割り当てる必要があります。したがって、攻撃タイプを”Pitchfork”に変更します。
チェックするログインリストを追加します:
Request Timerプラグインで、Intruderモジュールをリッスンするよう設定します:
テストを実行すると、生成されたリクエストと応答時間がタブに表示されます。ご覧のように、正しいログインに対する応答時間は著しく長いです。これにより、サーバーの応答時間の分析を通じて、アプリケーションがユーザーのログイン列挙に対して脆弱であることが証明されました。
どうすればいい?
この種の問題を解決する一つの方法は、サーバーの応答をランダムに遅延させる機能を追加することです:
しかしながら、この種の解決策の場合でも、データベースへの接続中のネットワークの遅延や、データベースの成長により生じる違いなどの状況を完全にコントロールすることはできません。
より良い解決策は、ユーザーが入力したデータの検証をバックグラウンドで非同期に実行し、試行中にユーザーに即時に通知することです。この場合、計算とそれに伴う遅延は攻撃者には見えません。