Node.jsでのタイミング攻撃-時間に反するとき

認証の試みに応答して、「入力したパスワードの5番目の文字が間違っています」などのメッセージを提供するサービス(またはWebアプリケーション)を想像してください。 それはばかげているようですね。 潜在的な攻撃者にこの種の情報を提供することにより、サービスのパスワードを「片付け」(ピックアップ、ブルートフォース)する機会を彼に与えるだけです。



同時に、これは、たとえば、認証のためのパスワードまたはトークンの調整中に文字列データ型を比較す​​るために最も単純なメカニズムを使用する場合に発生する事実上同じイベントです。









「タイミング攻撃」または「タイムアタック」自体は、攻撃者がアルゴリズムの実行にかかる時間を分析してシステムを侵害しようとする、オープンアクセスチャネルを介したシステムに対する攻撃です。 各操作(特に数学、加算、減算、べき乗など)には実行に一定の時間が必要であり、この時間は入力データによって異なる場合があります。 これらの操作にかかった時間を正確に測定することにより、攻撃者はシステムに入るために必要なデータを回復できます。



JavaScriptについて



はじめに戻ると、 「===」演算子に基づくJavaScript文字列比較メカニズムは、同じ長さの文字列の通常の反復のように動作し、文字の単純な列挙によって文字列を相互に比較し、比較される文字のペアが同一であり、予期しない場合に前進しますペアの文字の1つが異なる場合に停止します。



function isAuthenticated(user, token) { var correctToken = FetchUserTokenFromDB(user); return token === correctToken; }
      
      





不要なコード例



この操作は高速ですが、同時に安全ではありません。 調査によると、攻撃者がインターネット経由で15〜100マイクロ秒、ローカルネットワーク経由で100ナノ秒の時間を測定することは難しくありません。 言い換えれば、攻撃者は、ヒントのように、どのようなシンボルが出現し、どのシンボルが出現しなかったかなど、このようなわずかな時間遅延の技術を使用することができます。 このようなシナリオの開発を防ぐには、指定されたパスワードに関係なく、処理に同じ時間がかかるように文字列処理メカニズムを実装する必要があります。



たとえば、出力で0を取得しながら、2つのパスワードに論理演算xorを適用します。



 var mismatch = 0; for (var i = 0; i <a.lenght; ++i) { mismatch | = (a.charCodeat(i)) ^ b.charCodeAt(i)); } return mistmatch;
      
      





Node.jsについて



Node.js自体は、スケーラブルで非同期のフレームワークとして設計されました。 Node.jsコードの一部が1つまたは別のブロックアクション(ファイルを開く、ネットワークソケットへの書き込みなど)を呼び出したい場合、コールバック関数(コールバック)を登録し、対応するアクションを開始してから終了します。 コールバック自体は、イベントループと呼ばれるメカニズムを使用して呼び出されます。



イベントループは、操作をカーネルにアップロードすることにより(可能な場合はいつでも)Node.jsがノンブロッキングI / Oを(JavaScriptがシングルスレッドであっても)実行できるようにするものです。 最新のコアのほとんどはマルチスレッドであるため、バックグラウンドで実行されるいくつかの操作を処理できます。 これらの操作のいずれかが完了すると、カーネルはNode.jsに、その操作に対応するコールバック関数を最終的に実行するためにポーリングキューに追加できることを伝えます。



イベント駆動型モデルは、それで表されるスレッドが待機状態になることはないため、それ自体非常にスケーラブルです。 しかし、同時に、1つまたは別の機能が完了する前に長時間かかることがあるため、これは問題として述べられています。



最初にNode.jsに基づくサーバーはカーネルごとに1つのスレッドを開始するため(デフォルト)、いずれかの「長時間」機能がプロセッサーコア全体を占有し、他の機能をアイドル状態にすることができます。 上記の理由により、「スクリプトの実行に時間がかかりすぎる」というエラーメッセージがブラウザに表示されることがあります。 同時に、サーバーで「単純な」着信要求が発生します。



例で分解する



いくつかのエンドポイントを提供する小さなexample.comサービスがあるとします。



example.com/info



example.com/check



ローカルで実行するために使用できるサービスのソースは、 リンクからダウンロードできます。



エンドポイント/情報のリクエストには、IPアドレスとリクエスト数に関する情報が表示されます。



 "you are 172.25.20.157 request count on your IOLoop: 1"
      
      





適切なフォームでのリクエスト/チェックは、適切な文字の組み合わせを見つけることができたかどうかを示します。



 curl "http://example.com/check?val0=1&val1=1&val2=1&val3=1&val4=1" "you are 172.25.20.157 - At least one value is wrong!"
      
      





「攻撃」するシステムについて、事前に何を知っていますか?



  1. システムにアクセスするには、正しい文字列val0 = 1&val1 = 1&val2 = 1&val3 = 1&val4 = 1を提供する必要があります
  2. 番号のシーケンスは、おそらく1〜100の範囲にあります。
  3. アルゴリズムの実行時間は、ほとんどの場合、受け取った入力によって異なります。
  4. サーバーは、タイミング攻撃を防ぐために、少なくとも3秒待機してから答えを出します。


不明なのは、正しいログインの詳細が次のように見えることです。



Val0 = 4&val1 = 12&val2 = 77&val3 = 98&val4 = 35



そのため、サーバーが1つのリクエストの処理に約3秒かかることがわかっているため、簡易検索を使用して100 ^ 5の組み合わせを選択するには数千年かかる場合があります。 イベントループカウンターはいずれの場合もインクリメントされますが、 / infoエンドポイントを呼び出すことによってのみ、カウンターのステータスに関する情報を取得できます。



 $ curl "http://example.com/info" you are 172.25.50.175 request count on your IOLoop: 1 $ curl "http://example.com/info" you are 172.25.50.175 request count on your IOLoop: 2 $ curl "http://example.com/check?val0=1&val1=1&val2=1&val3=1&val4=1" you are 172.25.20.157 - At least one value is wrong! $ curl "http://example.com/info" you are 172.25.50.175 request count on your IOLoop: 4
      
      





数字のさまざまな組み合わせでリクエスト/チェックを送信しても、実行時間に大きな違いはありません。 アルゴリズムの動作には3秒もかかりません。 また、 / checkへのリクエストの処理中に/ infoにリクエストを送信すると、この調査に費やした手がかりが得られることに気付きました。 ここで、上で説明した一連のイベントの概念が助けになります。



エンドポイント/チェックへの呼び出し満たされている間、イベントループは制御を取得せず、エンドポイントコール/情報のハングオーバーを強制します。 これとは対照的に、setTimeout関数は単にスケジュールされたイベントをログに記録し、制御を提供するだけで、 / infoコントローラーへの要求を非常に迅速に処理できます。 今、タイミングをどのように適用しますか? とても簡単です。 要求を/ checkに送信し、応答を待たずに、すぐに/ infoに要求を送信し、応答時間を測定します。



 $ curl "http://example.com/check?val0=1&val1=1&val2=1&val3=1&val4=1" you are 172.25.20.157 - At least one value is wrong! $ curl "http://example.com/info" you are 172.25.50.175 request count on your IOLoop: 2
      
      





本質的に、そのようなリクエスト中に次のことが起こります。







ご覧のように、測定により、 val0 = 4に設定すると、システムがわずかな遅延で応答することがわかります。 したがって、このような遅延に依存して、最終的に必要なすべてのコードシーケンスを復元できます。



保護の方法:





おわりに



今日のタイミング攻撃は、小規模なアプリケーションと大規模なアプリケーションの両方にとって真の脅威になり得ます。 実践では、システムへのリクエストの実行時間のわずかな違いからでも、攻撃者が使用できる十分な情報を取得できることが示されています。 特に、Node.jsの観点からは、イベントループを使用できます。



参照資料



投稿を書くとき、私はこの資料を使用しました

さらに、いくつかのウィキペディアのコンテンツ。



All Articles