このコードがセキュリティ上の欠陥である理由を理解しようとしています。私の理解では、プログラムがオンになっているときにシステム時間を使用して乱数シードを生成するのは安全ではありませんが、それはどのように推測できますか? エクスプロイトの可能性があるかどうかはわかりません。
D. Wagner による DMCA 要求により削除されたコード例
このコードがセキュリティ上の欠陥である理由を理解しようとしています。私の理解では、プログラムがオンになっているときにシステム時間を使用して乱数シードを生成するのは安全ではありませんが、それはどのように推測できますか? エクスプロイトの可能性があるかどうかはわかりません。
D. Wagner による DMCA 要求により削除されたコード例
まず、コードには値がまったく使用されないというバグがありますtime_in_sec
。次の行でそれを上書きします。
seed = time_micro_sec >> 7;
さらに、time_micro_sec
1000000 の可能な値しかなく、7 だけ右にシフトした後、7813 の可能な値のみに減少します。このスペースは、力ずくで検索するのは簡単です。
これらのバグを修正したとしても、結局のところsrand()
/rand()
乱数ジェネレーターは暗号的に強力な PRNG ではありません。srand()
インターフェイスは最終的に、 が引数を取るという事実によって制限されますunsigned int
。一般的なプラットフォームでは、初期状態のエントロピーがわずか 32 ビットに制限されます。これは、シードに対するブルート フォース攻撃を防ぐには不十分です。
セキュリティ上重要な乱数にはsrand()
/を使用しないでください。rand()
プログラムを実行したときのシステム時刻を予測できた場合 (プログラムを実行している場合、これはストレッチではありません)、シードに入力される値を予測して、「乱数」が何であるかを判断できます。ジェネレーターが生成されます。
意図的ではないと思われる完全なバグを無視します...
これが問題になる正確な時間を予測する必要はありません。大まかな時間だけです。任意のシードに対して、生成されるランダム値は完全に予測可能なシーケンスです。したがって、アクションを繰り返し実行する場合は、どのシードが見ているパターンに一致するかを推測しようとすることができます 開始時間を 1 分以内に絞り込むことができれば、たとえば、検索するシードは 60,000 だけです (ミリ秒と仮定しますが、ミリ秒、マイクロという名前の変数、およびどちらにもないように見える値に関するコメントを混ぜてください)。これは単純かもしれません。1 日はわずか 86,400,000 です。これよりも大きくなりますが、実行可能です。
たとえば、アプリケーションをクラッシュさせて再起動を強制する力があれば、シードを予測してさらに悪用することがはるかに簡単になります。そうでない場合は、ローカル アクセスがあれば、開始時刻を簡単に見つけることができます。リモート攻撃の場合はより困難になる可能性がありますが、たとえば MMO では、サーバーの再起動は予測可能である可能性があり、銀行は日曜日の午後 10 時から午前 4 時までサービスの更新を行う可能性があります。
基本的に、安全なものが必要な場合は、最初から安全であるように設計されたものを使用してください。