web-dev-qa-db-ja.com

総当たり攻撃の防止:いつ、どこで?

「安全な」ログインシステムを設計します。力ずくの防止に力を入れましょう。私のAndroidクライアントには、ユーザーがログインを試行した回数をカウントするカウンターがあり、誤った認証情報が使用されています。3回失敗すると、ログインボタンとパスワードフィールドが無効になります、ユーザーにアプリの再起動を強制し、ブルートフォース攻撃をブロックします。これは正しいことですか?

または、サーバーにカウンターを配置する必要がありますか?しかし、サーバーでDoSが発生する可能性があります。同時に大量のブルートフォース攻撃を受けた場合、そうですか。

アイデアは無数の入力を停止することなので、私の意見ではこれはアプリケーション側で、私の場合はAndroidクライアントで)実行できます。

私は提案を受け入れます。

4
rew1nd

クライアント側の対策は部分的な(そしてほとんどの場合は表面的な)ソリューションであり、これは深刻でない試みを制限することしかできません。 深刻な試行は、ログインURL/APIが検出されたためにサーバーに直接ヒットするか、インターセプトプロキシを介してクライアントを実行し、必要な詳細を取得しますブルートフォースランを作成します。

一般的に、堅牢な防御では、攻撃者は秘密鍵以外のシステムに関するすべてを知っていると想定する必要がありますKerckhoffの原理 )。その位置から開始する必要があります。

緩和策は次のとおりです。

  • 攻撃者が有効なユーザー名、無効なパスワード、またはロックアウトされたアカウントを判別するのを困難/不可能にします(基本的に最小限のフィードバック、つまり「無効なユーザー名」または「パスワードが長すぎます」メッセージはありませんが、これが重要な場合は一意のインシデントコードを発行しますユーザーサポート)。 My1のコメントにあるように、ここではオープン登録が弱点になる可能性があります。
  • 成功または失敗以外の何かを判別することを難しくします。失敗したログインは成功したログインと同じ時間かかるはずです。これは通常、両方を人為的に長くすることを意味します(200msが開始点です)
  • ナンスまたは時間ベースまたはセッションベースのトークンを使用してログインAPIをマルチステップにして、自動化された攻撃を複雑にし、分散型攻撃を防止します。または、クライアント側の作業証明を追加します(クライアント側のパスワードハッシュは1つのオプションですが、 慎重な考慮 が必要です)。
  • パスワードスペースが十分に大きいことを確認し、パスワードマネージャの使用を推奨(およびサポート!)してください。
  • アカウントのロックアウトとソースのIPロックアウトを使用して、ロックアウト時間を指数関数的に増やします(たとえば、失敗するたびにロックアウト時間を2倍にします。これにより、パスワードを間違えたユーザーを煩わせないようにすることができます)。コメントで述べたように、これはDOSの機会なので、トレードオフを慎重に検討してください
  • 適応レート制御と悪意のあるアクティビティの検出を実装します(サーバー側で追加の状態とロジックが必要になるため、これは通常、他のソリューションよりも困難です)
  • 必要に応じて有効にできる「攻撃中」の操作モードを追加することを検討してください。これにより、ユーザーへの影響が最小限になるのが理想的です

CAPEC-112Brute Force から:

この攻撃の重要な要素は、潜在的な秘密空間を迅速に探索する攻撃者の能力です。防御側は攻撃者が利用できるリソースを制御できませんが、秘密スペースのサイズを制御できます。防御側は、そうするために必要な時間とリソースが情報の価値を超えることを確認することに依存する必要があります。

参照 CAPEC-49パスワードブルートフォーシング

23
mr.spuratic

ブルートフォース攻撃を防ぐ通常の方法は、サーバーに少し遅延を追加することです。

ユーザーによるコメントmimibis で指摘されているように、攻撃者はアプリを使用してDoSまたはDDoSを実行する必要はありません。攻撃者が必要とするのはエンドポイントだけであり、それをフラッディングすることができます。また、.apkファイルをリバースエンジニアリングするか、送信トラフィックを監視するだけで、エンドポイントを見つけることができます。

したがって、防御はサーバー側にある必要があります。ログインに失敗するたびに少し遅れて(1秒など)追加することにより、攻撃者が何百万ものユーザー名とパスワードの組み合わせを試すことは現実的ではなくなります。

一般的にDDoS攻撃からサーバーを保護するには、強力なサーバーファームが必要か、CloudFlareなどのサービスを使用します。

重要な側面の1つは、デバイスを認証するために使用できるあらゆる種類のキーマテリアルがデバイスに格納されているかどうか、またはユーザーが新しいデバイスを入手し、アプリをダウンロードしてログインできるかどうかです。

デバイスにそのようなキーマテリアルがある場合、サーバーがデバイスごとにレート制限を適用することが可能です。サーバーサイドにレート制限を適用するその他の方法(IPごとまたはユーザー名ごとのレート制限など)は、潜在的なDoS攻撃ベクトルです。これは、サーバーにパスワードの検証の一部としてCPU負荷の高い計算を実行させることによって、または一時的なロックアウトによってレート制限が実装されるかどうかに関係なく当てはまります。

クライアントコードとサーバーコードの両方を制御している場合、検証のCPUの重い部分がクライアント側で実行されるプロトコルを設計できますが、サーバーはソルトハッシュを実行して、サーバー側の検証の利点を確実に維持します。明らかに、そのようなものを最初から実装すると、設計または実装の欠陥によってもたらされる脆弱性のリスクがあります。

クライアント側でCPUを集中的に使用することの利点は、DoS攻撃ベクトルをほとんど排除できることです。クライアント側でCPUを集中的に使用することの欠点は、クライアントのCPUリソースが制限される可能性があることです。

上記のアプローチを組み合わせることが可能です。最初のログイン時に、クライアントにソルトを送信するなどして数秒間ハッシュを実行させ、何回かハッシュを実行させ、最後にサーバーが最後のラウンドのハッシュを別のソルトで実行することができます。パスワードが受け入れられると、デバイスはトークンを送信します。これにより、クライアントは、将来的にははるかに安価な2次ハッシュを使用して同じアカウントで認証できるようになります。サーバーは、トークンが期限切れになり、クライアントがより遅いハッシュに戻る前に、トークンを使用したログイン試行の失敗回数を制限することができます。

繰り返しますが、このようなデザインにセキュリティの欠陥を導入する方法はたくさんあるので、総当たり攻撃のリスクに対してそのリスクを回避する必要があります。

0
kasperd

デバイスのターピットと作業の証明を組み合わせることができる場合があります。

すべてのデバイスがデバイスIDとして自己署名キー(〜4096ビット)を使用して接続する必要があり、それがレート制限に使用された場合:

どちらか

  • 各デバイスは、新しいキーの生成に過度の時間を費やしています。したがって、パスワードの試行を遅らせる
  • 多くのログインは同じクライアントキーで発生します。単一の悪意のあるデバイスであることが保証されているため、サービスDOSのリスクなしにブロックできます。
  • キーとログインのボットネットスタイルの共有が発生します。新しいキーの生成に使用できるデバイスの能力によって制限されます---サービスのターゲットの価値に対して、ユーザーが最初のログイン/証明書キーの生成を待つ時間はどれくらいですか?

または、それを誰か他の人の問題にする-パブリック2要素認証システムを使用します。

0
CGretski