156

まず、少し背景があります。CodeIgniterにauth + authシステムを実装していることは周知の事実であり、これまでのところ(いわば)勝っています。しかし、私はかなり重要な課題に遭遇しました(ほとんどの認証ライブラリは完全に見逃していますが、適切に処理することを主張しています):大規模な分散型の可変ユーザー名ブルートフォース攻撃にインテリジェントに対処する方法。

私はすべての通常のトリックを知っています:

  1. IP /ホストごとの失敗した試行の数を制限し、違反者のアクセスを拒否します(Fail2Banなど)-ボットネットがよりスマートに成長したため、これは機能しなくなりました
  2. 上記を既知の「不良」IP/ホスト(DenyHostsなど)のブラックリストと組み合わせる-これは、ボットネットが1位に該当することに依存していますが、ボットネットはますますそうではありません
  3. 従来の認証と組み合わせたIP/ホストホワイトリスト(動的IPユーザーとほとんどのWebサイトでの高いチャーンでは残念ながら役に立たない)
  4. N分/時間の期間内に失敗する試行の数にサイト全体の制限を設定し、その後のすべてのログイン試行を数分/時間の間スロットリング(一時停止)します(DoSがあなたを攻撃するとボットネットの子供の遊びになるという問題があります)
  5. ログイン/パスワードオプションがないすべてのユーザーに必須のデジタル署名(公開鍵証明書)またはRSAハードウェアトークン(確かなソリューションですが、閉じた専用サービスでのみ実用的です)
  6. 強制された超強力なパスワードスキーム(例:記号付きの25を超える意味のない文字-繰り返しますが、カジュアルユーザーには実用的すぎます)
  7. そして最後に、CAPTCHA(ほとんどの場合は機能しますが、ユーザーにとっては煩わしく、断固とした機知に富んだ攻撃者に対しては事実上役に立たない

さて、これらは理論的に実行可能なアイデアにすぎません。サイトを大きく開いてしまうようなごみのアイデアはたくさんあります(たとえば、些細なDoS攻撃など)。私が欲しいのはもっと良いものです。そして、より良い意味で、私は意味します:

  • DoSおよびブルートフォース攻撃に対して安全(+)である必要があり、わずかに卑劣なボットがレーダーの下で動作し続けることを可能にする可能性のある新しい脆弱性を導入してはなりません。

  • 自動化する必要があります。人間のオペレーターが各ログインを確認したり、疑わしいアクティビティを監視したりする必要がある場合、実際のシナリオでは機能しません。

  • それは主流のウェブの使用のために実行可能でなければなりません(すなわち、非プログラマーによって実行されることができる大量の解約、大量の、そしてオープンな登録)

  • カジュアルなユーザーがイライラしたりイライラしたりする(そしてサイトを放棄する可能性がある)まで、ユーザーエクスペリエンスを妨げることはできません。

  • 彼らが本当に安全な子猫でない限り、それは子猫を巻き込むことはできません

(+)「安全」とは、少なくとも、パスワードを秘密にしておくパラノイドユーザーの能力と同じくらい安全であることを意味します

だから-聞いてみよう!どうしますか?私が言及していないベストプラクティスを知っていますか(ああ、そう言ってください)?私は自分自身のアイデアを持っていることを認めます(3と4のアイデアを組み合わせます)が、恥ずかしい思いをする前に、真の専門家に話させます;-)

4

16 に答える 16

71

元の投稿の方法 3 と 4 を一種の「ファジー」または動的ホワイトリストに組み合わせてから、ホワイトリストに登録されていない IP をブロックせずに、それらを調整して元に戻します .

この対策は、この非常に特殊なタイプの攻撃を阻止することのみを目的としていることに注意してください。もちろん、実際には、認証に対する他のベストプラクティスアプローチと組み合わせて機能します。固定ユーザー名のスロットリング、IP ごとのスロットリング、コード強制の強力なパスワードポリシー、スロットリングされていない Cookie ログイン、すべての同等のパスワードを保存する前のハッシュ化、決してセキュリティ質問などの使用

攻撃シナリオに関する仮定

攻撃者が変数のユーザー名をターゲットにしている場合、ユーザー名のスロットリングは作動しません。攻撃者がボットネットを使用しているか、広範囲の IP にアクセスしている場合、当社の IP スロットリングは無力です。攻撃者がユーザーリストを事前にスクレイピングしている場合 (通常はオープン登録 Web サービスで可能)、「ユーザーが見つからない」エラーの数に基づいて進行中の攻撃を検出することはできません。また、システム全体 (すべてのユーザー名、すべての IP) に制限的なスロットリングを適用すると、そのような攻撃は、攻撃とスロットリング期間の間、サイト全体を DoS 攻撃します。

ですから、何か他のことをする必要があります。

対策の最初の部分: ホワイトリスト登録

私たちがかなり確信で​​きることは、攻撃者が数千人のユーザーの IP アドレスを検出して動的にスプーフィングすることができないということです(+)。これにより、ホワイトリストが実現可能になります。つまり、ユーザーごとに、ユーザーが以前 (最近) ログインした (ハッシュ化された) IP のリストを保存します。

したがって、私たちのホワイトリスト スキームは、ロックされた「フロント ドア」として機能し、ユーザーがログインするには、認識された「適切な」IP のいずれかから接続する必要があります。この「正面玄関」へのブルート フォース攻撃は事実上不可能です(+)。

(+) 攻撃者がサーバー、すべてのユーザーのボックス、または接続自体のいずれかを「所有」していない限り、これらの場合、「認証」の問題はなくなり、本物のフランチャイズ サイズのプルが発生します。 -プラグFUBARの状況

対策の 2 番目の部分:認識されていない IP のシステム全体のスロットリング

ユーザーが頻繁にコンピューターを切り替えたり、動的 IP アドレスから接続したりするオープン登録 Web サービスでホワイトリストを機能させるには、認識されていない IP から接続するユーザーに対して「猫のドア」を開いたままにしておく必要があります。その秘訣は、ボットネットが立ち往生し、正当なユーザーができるだけ煩わされないようにドアを設計することです。

私のスキームでは、たとえば 3 時間 (サービスの種類によっては、より短いまたはより長い期間を使用する方が賢明な場合があります) にわたって、承認されていない IP による失敗したログイン試行の非常に制限的な最大数を設定することによってこれが達成されます。その制限をグローバルにします。すべてのユーザー アカウントに対して。

この方法を使用すると、遅い (試行間隔が 1 ~ 2 分) 総当たり攻撃でさえ検出され、迅速かつ効果的に阻止されます。もちろん、非常に遅いブルート フォースは依然として見過ごされる可能性がありますが、速度が遅すぎると、ブルート フォース攻撃の目的そのものが無効になります。

このスロットリング メカニズムで達成したいことは、最大制限に達した場合、「キャット ドア」がしばらくの間バタンと閉じますが、通常の方法で接続する正当なユーザーに対してフロント ドアは開いたままになるということです。

  • 認識されたIPの1つから接続することによって
  • または永続的なログイン Cookie を使用して (どこからでも)

攻撃中に影響を受ける正当なユーザーのみ。スロットリングがアクティブ化されている間 - 永続的なログイン Cookie を持たないユーザーで、不明な場所から、または動的 IP を使用してログインしていた可能性があります。これらのユーザーは、スロットリングが解除されるまでログインできません (攻撃者がスロットリングにもかかわらずボットネットを実行し続けた場合、時間がかかる可能性があります)。

この小さなユーザーのサブセットが、ボットがまだドアを叩いているときでも、密閉されている猫のドアを通り抜けることができるようにするために、CAPTCHA を使用した「バックアップ」ログイン フォームを使用します。そのため、「申し訳ありませんが、現時点ではこの IP アドレスからログインできません」というメッセージが表示された場合は、「安全なバックアップ ログイン - HUMANS のみ (ボット: 嘘をつかない)」というリンクを含めます。冗談はさておき、彼らがそのリンクをクリックすると、サイト全体のスロットリングをバイパスする reCAPTCHA 認証済みのログイン フォームが提供されます。そうすれば、彼らが人間であり、正しいログインとパスワードを知っている (そして CAPTCHA を読み取ることができる)場合、たとえ未知のホストから接続していて自動ログイン Cookie を使用していない場合でも、サービスが拒否されることはありません

ああ、そして明確にするために:私はCAPTCHAは一般的に悪だと考えているので、「バックアップ」ログインオプションはスロットリングがアクティブな間だけ表示されます.

このような継続的な攻撃が依然として DoS 攻撃の形態を構成することは否定できませんが、説明されているシステムが整っていれば、ユーザーのごく一部であると思われるユーザー、つまり、 「remember me」Cookie であり、攻撃が発生しているときにたまたまログインし、通常の IP からログインしておらず、CAPTCHA を読み取ることができない. これらすべての基準にノーと言える人、特にボットと本当に不運な身体障害者だけが、ボット攻撃の際に追い返されます。

編集:実際には、CAPTCHA に挑戦したユーザーでも「ロックダウン」中に通過できるようにする方法を考えました: バックアップの CAPTCHA ログインの代わりに、または補足として、使い捨てのオプションをユーザーに提供します。 、ユーザー固有のロックダウン コードがメールに送信され、スロットリングをバイパスするために使用できます。これは間違いなく私の「煩わしさ」のしきい値を超えていますが、これはごく一部のユーザーの最後の手段としてのみ使用されており、アカウントからロックアウトされるよりはましであるため、許容範囲内です。

(また、攻撃がここで説明した厄介な分散バージョンよりも洗練されていない場合、これは何も起こらないことに注意してください。攻撃がほんの数個の IP から来ているか、少数のユーザー名にしかヒットしていない場合は、はるかに早く阻止されます。 、サイト全体への影響なし)


それで、それが健全であり、私が見逃したより簡単な解決策がないことを確信したら、それが私の認証ライブラリに実装する対策です。実際のところ、セキュリティにおいて間違ったことを行う巧妙な方法は数多くあります。私は、誤った仮定や絶望的に欠陥のある論理を作ることを避けません。したがって、すべてのフィードバック、批判、改善、微妙な点などは高く評価されます。

于 2009-01-27T07:17:56.303 に答える
17

いくつかの簡単な手順:

特定の一般的なユーザー名をブラックリストに登録し、ハニーポットとして使用します。管理者、ゲストなど...誰にもこれらの名前のアカウントを作成させないでください。そうすれば、誰かがそれらにログインしようとした場合、それは彼らがすべきでないことをしている誰かであることがわかります。

サイトで本当の力を持っている人は誰でも安全なパスワードを持っていることを確認してください。管理者/モデレーターに、文字、数字、記号を組み合わせた長いパスワードを要求します。説明付きの通常のユーザーからの簡単なパスワードを拒否します。

あなたができる最も簡単なことの1つは、誰かが自分のアカウントにログインしようとしたときに人々に知らせ、そうでない場合はインシデントを報告するためのリンクを提供することです。「誰かが水曜日の午前4時20分にあなたのアカウントにログインしようとしました。これがあなたでない場合はここをクリックしてください。」のような簡単なメッセージ。それはあなたが攻撃に関するいくつかの統計を保持することを可能にします。不正アクセスが急増していることがわかった場合は、監視とセキュリティ対策を強化できます。

于 2009-01-28T01:04:32.110 に答える
11

ブルートフォース攻撃のMOを正しく理解していれば、1つ以上のユーザー名が継続的に試行されます。

ここではまだ見たことがないと思う2つの提案があります。

  • 私はいつも、すべてのユーザーが間違ってログインするたびに、少し遅れる(1秒程度)のが標準的な方法だと思っていました。これはブルートフォースを阻止しますが、1秒の遅延が辞書攻撃を阻止するのにどれくらいの時間がかかるかはわかりません。(10,000語の辞書== 10,000秒==約3時間。うーん。十分ではありません。)
  • サイト全体の速度を落とす代わりに、ユーザー名を絞ってみませんか。スロットルは、間違った試行を行うたびにますます厳しくなります(限界まで、実際のユーザーが引き続きログインできるように推測します)

編集:ユーザー名スロットルに関するコメントへの応答:これは、攻撃のソースに関係なく、ユーザー名固有のスロットルです。

ユーザー名が抑制されている場合、調整されたユーザー名攻撃(マルチIP、IPごとの単一推測、同じユーザー名)でさえも捕らえられます。攻撃者がタイムアウト中に別のユーザー/パスを自由に試すことができる場合でも、個々のユーザー名はスロットルによって保護されます。

攻撃者の観点からすると、タイムアウト中に、最初に100個のパスワードを推測し、アカウントごとに1つの間違ったパスワードをすばやく発見できる可能性があります。同じ期間で50秒の推測しかできない場合があります。

ユーザーアカウントの観点からは、推測が複数のソースからのものであっても、パスワードを破るのに同じ平均数の推測が必要です。

攻撃者にとっては、せいぜい1つのアカウントと同じように100のアカウントを壊すのですが、サイト全体でスロットルを調整していないため、スロットルをすばやく上げることができます。

追加の改良点:

  • 複数のアカウントを推測しているIPを検出します-408リクエストタイムアウト
  • 同じアカウントを推測しているIPを検出します-408多数の推測(たとえば100)の後にタイムアウトを要求します。

UIのアイデア(このコンテキストでは適切でない場合があります)。これにより、上記も改善される可能性があります。

于 2009-01-26T15:44:27.313 に答える
7

以前、 How can I throttle user login attempts in PHPで非常によく似た質問に答えていました。ここで提案された解決策を繰り返しますが、実際のコードを確認することは有益であり、役立つと考える人が多いと思います。現在、CAPTCHA バスターで使用されるアルゴリズムの精度が高まっているため、CAPTCHA を使用することが最善の解決策ではない可能性があることに注意してください。

スロットリングを単一の IP またはユーザー名に連鎖させるだけでは、DoS 攻撃を防ぐことはできません。地獄、この方法を使用しても、連射ログイン試行を実際に防ぐことはできません.

なんで? スロットリングの試行をバイパスするために、攻撃が複数の IP とユーザー アカウントにまたがる可能性があるためです。

理想的には、サイト全体で失敗したすべてのログイン試行を追跡し、それらをタイムスタンプに関連付ける必要があるという投稿を他の場所で見ました。

CREATE TABLE failed_logins(
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(16) NOT NULL,
    ip_address INT(11) UNSIGNED NOT NULL,
    attempted DATETIME NOT NULL
) engine=InnoDB charset=UTF8;

特定の時間内に失敗したログインの総数に基づいて、特定の遅延を決定します。これは、ユーザー数とパスワードを思い出す (および入力する) ことができるユーザーの数に基づいて時間の経過とともに変化するfailed_loginsため、テーブルから取得した統計データに基づいている必要があります。


10 failed attempts = 1 second
20 failed attempts = 2 seconds
30 failed attempts = reCaptcha

失敗したログイン試行ごとにテーブルをクエリして、特定の期間 (たとえば 15 分間) の失敗したログインの数を見つけます。


SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute);

一定期間の試行回数が制限を超えた場合は、制限を強制するか、一定期間の試行失敗回数がしきい値を下回るまで、すべてのユーザーにキャプチャ (reCaptcha) の使用を強制します。

// array of throttling
$throttle = array(10 => 1, 20 => 2, 30 => 'recaptcha');

// assume query result of $sql is stored in $row
$sql = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$latest_attempt = (int) date('U', strtotime($row['attempted']));
// get the number of failed attempts
$sql = 'SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)';
// assume the number of failed attempts was stored in $failed_attempts
krsort($throttle);
foreach ($throttle as $attempts => $delay) {
    if ($failed_attempts > $attempts) {
        // we need to throttle based on delay
        if (is_numeric($delay)) {
            $remaining_delay = time() - $latest_attempt - $delay;
            // output remaining delay
            echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
        } else {
            // code to display recaptcha on login form goes here
        }
        break;
    }
}

特定のしきい値で reCaptcha を使用すると、複数の面からの攻撃が最小限に抑えられ、通常のサイト ユーザーが正当なログイン試行の失敗に対して大幅な遅延を経験することはありません。CAPTCHA が無効化される可能性があることは既に拡張されているため、防止を保証することはできません。おそらく「この動物に名前を付ける」の変形であり、代替として非常にうまく機能する可能性があります。

于 2010-07-19T11:21:08.533 に答える
6

この問題の費用便益分析を行ったかどうかを尋ねなければなりません。多数のパスワードを推測するのに十分な Web プレゼンスを持ち、IP ごとにおそらく 3 ~ 5 のリクエストを送信する攻撃者から身を守ろうとしているようです (IP スロットルを却下したため)。その種の攻撃のコストは (概算で) いくらですか? 保護しようとしているアカウントの価値よりも高価ですか? あなたが持っているものを欲しがっている巨大なボットネットはいくつありますか?

答えは「いいえ」かもしれませんが、もしそうなら、何らかのセキュリティ専門家から助けを得られることを願っています。プログラミング スキル (および StackOverflow スコア) は、セキュリティのノウハウと強く相関しません。

于 2009-01-28T22:40:02.603 に答える
5

Jens のスキームを疑似状態遷移図/ルールベースにまとめると、次のようになります。

  1. ユーザー + パスワード -> エントリ
  2. ユーザー + !パスワード -> 拒否
  3. ユーザー + 既知の IP(ユーザー) -> 正面玄関、// never throttle
  4. ユーザー + unknown_IP(ユーザー) -> catflap
  5. (#denied > n) catflaps(サイト) 経由 -> スロットル catflaps(サイト)// slow the bots
  6. catflap + スロットル + パスワード + キャプチャ -> エントリ// humans still welcome
  7. catflap + スロットル + パスワード + !captcha -> 拒否// a correct guess from a bot

所見:

  • フロントドアは絶対に絞らないでください。エルボニア州警察はあなたの家にあなたのコンピューターを持っていますが、あなたを尋問することはできません。ブルート フォースは、コンピューターから実行可能なアプローチです。
  • 「パスワードをお忘れですか?」リンクをクリックすると、メール アカウントが攻撃対象になります。

これらの観察結果は、対抗しようとしている攻撃とは異なるタイプの攻撃をカバーしています。

于 2009-01-28T22:14:23.170 に答える
4

ゆっくりと分散したブルートフォースから防御しようとしているようです。あなたがそれについてできることはそれほど多くありません。PKIを使用しており、パスワードログインは使用していません。それは役に立ちますが、クライアントが時々ワークステーションを偶然見つけた場合、これはあまり当てはまりません。

于 2009-01-26T10:04:21.757 に答える
3

Disclaimer: I work for a two-factor company, but am not here to plug it. Here're some observations.

Cookies can be stolen with XSS and browser vulns. Users commonly change browsers or clear their cookies.

Source IP addresses are simultaneously dynamically variable and spoofable.

Captcha is useful, but doesn't authenticate a specific human.

Multiple methods can be combined successfully, but good taste is certainly in order.

Password complexity is good, anything password-based critically depends on passwords having sufficient entropy. IMHO, a strong password written down in a secure physical location is better than a weak password in memory. People know how to evaluate the security of paper documents much better than they know how to figure the effective entropy in their dog's name when used as a password for three different websites. Consider giving users the ability to print out a big or small page full of one-time use pass codes.

Security questions like "what was your high-school mascot" are mostly another lousy form of "something you know", most of them are easily guessable or outright in the public domain.

As you noted, throttling back failed login attempts is a trade-off between preventing brute-force attacks and ease of DoSing an account. Aggressive lockout policies may reflect a lack of confidence in password entropy.

I personally don't see the the benefit to enforcing password expiration on a website anyway. Attacker gets your password once, he can change it then and comply with that policy just as easily as you can. Perhaps one benefit is that the user might notice sooner if the attacker changes the account password. Even better would be if the the user were somehow notified before the attacker gained access. Messages like "N failed attempts since last login" are useful in this respect.

The best security comes from a second factor of authentication which is out-of-band relative to the first. Like you said, hardware tokens in the "something you have" are great, but many (not all) have real admin overhead associated with their distribution. I don't know of any biometric "something you are" solutions good for websites. Some two-factor solutions work with openid providers, some have PHP/Perl/Python SDKs.

于 2009-07-29T05:33:09.667 に答える
1

私の最大の推奨事項は、アカウントへの不正なログイン試行をユーザーに通知することです。ユーザーは、誰かが実際にアカウントにアクセスしようとしているという証拠が提示された場合、パスワードの強度をより真剣に受け止める可能性があります。 。

兄のmyspaceアカウントをハッキングした人を実際に見つけました。彼らは、私が設定したgmailアカウントに侵入しようとし、受信トレイにある「メールでパスワードをリセット」機能を使用したためです。

于 2009-06-10T15:59:56.780 に答える
1
  1. 通常のパスワードを入力する前にワンタイムパスワードを要求するのはどうですか?それは、誰かがメインのパスワードを推測する多くの機会を得る前に攻撃していたことを非常に明白にしますか?

  2. ログイン失敗のグローバルカウント/レートを維持します(これは攻撃の指標です)。攻撃中は、ログイン失敗についてより厳密になります。たとえば、IPをより迅速に禁止します。

于 2009-01-26T10:37:30.897 に答える
0

何人かの人々が代替の人間のメカニズムとして CAPTCHA を含めたので、CAPTCHA の有効性に関する以前の StackOverflow の質問とスレッドを追加します。

reCaptcha は、クラック / ハッキング / OCR された / 敗北した / 壊れたことがありますか?

CAPTCHA を使用しても、スロットリングやその他の提案による改善が制限されることはありませんが、フォールバックとして CAPTCHA を含む回答の数は、セキュリティを破ろうとしている人々が利用できる人間ベースの方法を考慮する必要があると思います.

于 2009-03-05T22:25:37.127 に答える
0

完璧な答えがあるとは思いませんが、攻撃が感知された場合にロボットを混乱させようとすることに基づいてアプローチする傾向があります.

私の心のトップから:

別のログイン画面に切り替えます。実際には表示される複数のユーザー名とパスワードの空白がありますが、適切な場所にあるのはそのうちの 1 つだけです。フィールド名はランダムです。ログイン画面とともにセッション キーが送信され、サーバーはどのフィールドが何なのかを知ることができます。成功しても失敗しても破棄されるため、リプレイ攻撃を試みることはできません。パスワードを拒否すると、新しいセッション ID が取得されます。

間違ったフィールドにデータを入力して送信されたフォームはすべて、ロボットから送信されたものと見なされます。つまり、ログインが失敗し、期間が経過し、その IP が調整されます。ランダムなフィールド名が正当なフィールド名と決して一致しないことを確認して、パスワードを覚えているものを使用している人が誤解を招かないようにしてください。

次に、別の種類のキャプチャはどうでしょうか。人間には問題を引き起こさない一連の質問があります。ただし、それらはランダムではありません。攻撃が開始されると、全員に質問 #1 が与えられます。1 時間後、質問 #1 は破棄され、二度と使用されなくなり、全員が質問 #2 を受け取ります。

攻撃者は、質問が使い捨てであるため、データベースをダウンロードして自分のロボットに入れることはできません。何かを行うには、1 時間以内にボットネットに新しい指示を送信する必要があります。

于 2009-01-27T01:17:42.787 に答える
0

ユーザーのパスワードの強度に基づいて調整することもできます。

ユーザーがパスワードを登録または変更すると、パスワードの強度評価 (1 ~ 10 など) が計算されます。

「password」などのスコアは 1 ですが、「c6eqapRepe7et*Awr@ch」のスコアは 9 または 10 で、スコアが高いほどスロットリングにかかる​​時間が長くなります。

于 2011-01-27T04:11:08.673 に答える
0

Bit late here but I was thinking, assuming a hard case - the attacker uses a lot of random IPs, random user names and a random password selected from say a list of the 10,000 most popular.

One thing you could do, especially if the system seems under attack in that there are a lot of wrong password attempts on the system and especially if the password is low entropy is to ask a secondary question like what are your parents first names, for example. If an attacker hits a million accounts trying the password 'password1' there's a good chance they'll get a lot but their odds of also getting the names right would reduce successes dramatically.

于 2015-11-23T23:52:53.130 に答える