過去 2 回の学校採用面接中に、興味深い現象について友人と話しました。このコースでは、ほとんどの学生は暗号化の基本的な知識さえ持っていませんが、一部の学生は基本的な知識を持っています。
そこで、ここでは簡単な基本的な暗号化の知識についてお話したいと思います。これにはアルゴリズムの実装は含まれませんが、問題を理解しやすくするために一般的な脆弱性シナリオに関連したもので、ちょっとした入門編です。ポイント。
この記事では主に乱数について説明します。乱数は実際には非常に幅広く、暗号技術の基礎とも言えます。
乱数を不適切に使用すると、重大なセキュリティ上の問題が発生する可能性が高く、これらのセキュリティ上の問題は通常、比較的隠蔽されます。
乱数はコンピューター アプリケーションで広く使用されており、最もよく知られているアプリケーションは暗号化です。この記事では主に、乱数の使用によって引き起こされる Web セキュリティのリスクについて説明します。
まず乱数について簡単に見てみましょう
乱数は分類されています真の乱数と擬似乱数として、私たちのプログラムでは基本的に擬似乱数を使用しますが、擬似乱数は強い擬似乱数と弱い擬似乱数に分けられます。
真の乱数は、コイン、サイコロ、ホイールを投げる、電子部品からのノイズ、核分裂などを使用するなどの物理実験を通じて取得されます。
特定のアルゴリズムとシードを通じて取得された擬似乱数。このソフトウェアは、疑似乱数
強力な疑似乱数 、予測不可能な乱数
弱い擬似乱数、予測しやすい乱数
乱数には以下の 3 つの特徴があります。 🎜 >
ランダム性: 統計的な偏差はなく、完全にカオスなシーケンスです
予測不可能性 :過去の配列から次に出現する数字を推測することはできない
非再現性 :配列そのものを保存しない限り、同じ配列を再現することはできないたとえば、シーケンス
アルゴリズム + シード です。
特定の擬似乱数生成器 PRNG には通常次のものが含まれます:CSRF トークン
ゲーム (ランダム要素の生成)
シャッフル
パスワード適用シナリオ
生成キー: 対称パスワード、メッセージ認証
は使用されませんでした。
は強力な擬似乱数を使用する必要がありますが、開発者 は弱い擬似乱数 を使用しました。
最初のケースは、簡単に言えば、乱数が必要であるということですが、開発者は乱数を使用せず、定数を指定しました。もちろん、sb は乱数を使用していないと憤慨する人も多いでしょう。ただし、まだたくさんあることを無視しないでください。主なシナリオは 2 つあります。 開発者には基本的な常識が欠如しており、乱数の使い方を知りません。
一部のアプリケーション シナリオとフレームワークには、インターフェイスのドキュメントが不完全であるか、開発者がそれを注意深く読んでいません。
たとえば、パスワードを取得するためのトークンには擬似乱数が必要ですが、多くの企業はユーザー名に基づいてトークンを直接生成します。
たとえば、OAuth2.0 では、サードパーティがCSRF 攻撃を防ぐには、状態パラメーターを CSRF トークンとして渡す必要があります。CSRF 攻撃の場合、多くの開発者はこのパラメーターをまったく使用しないか、固定値を渡します。認証者はこの値のビジネス レベルの有効性を検証できないため、OAuth CSRF 攻撃が発生します。
2 番目のケースの主な違いは、ほとんど (すべて?) 言語の API ドキュメントの基本ライブラリ (一般的に使用されるライブラリ) のランダム ライブラリです。弱い擬似ランダムなので、多くの開発者は当然それを直接使用します。しかし、最も重要かつ致命的なことは、弱い擬似乱数は暗号化では使用できないということです。
これはまだ最初の状況のパスワード取得シナリオですが、トークンの生成に関して、多くの開発者はタイムスタンプを乱数として使用します (md5 (タイムスタンプ)、md5 (タイムスタンプ + ユーザー名))。予測可能であるため、簡単に推測できます。 予測不可能性は、弱い擬似乱数と強い擬似乱数を区別するための重要な指標です。
もちろん、上記 2 つの状況に加えて、通常はまれですが、例外ではありません。
種子の漏洩、アルゴリズム 多くの場合、シードが漏洩した場合、乱数が漏洩したことを意味します。
乱数プールが不足しています。厳密に言えば、これも弱い擬似乱数です。乱数プールが不十分であるため、実際には乱数が予測可能になり、攻撃者が直接総当たり攻撃を行うことができるからです。
wooyun には非常に興味深い脆弱性が多数あり、それらはすべて乱数に関連しています。
追伸: 以下の例は基本的に wooyun の脆弱性の例からのものです。侵害がある場合は、削除のためにご連絡ください。
Oauth2.0 のこの問題は、wooyun の例に挙げたもの以外にも、実際に多くのメーカーで発生しています。 。
Oauth2.0 の state パラメーターでは、サードパーティ アプリケーションの開発者が CSRF トークン (乱数) を渡す必要があります。これが渡されない場合、または渡されたものが乱数でない場合は、次のような問題が発生します。 CSRF による任意のアカウントへのログイン:
Vipshop アカウントに関連する脆弱性により、CSRF を通じて任意のアカウントにログインできます
Renren-Baidu OAuth 2.0 redirect_uir CSRF 脆弱性
多くのパスワード取得シナリオでは、URL が送信されます。このトークンを推測すると、他のユーザーのパスワードを取得できます。
1. Shopex 4.8.5 のパスワード取得で新しく生成されたパスワードには予測可能な脆弱性があります
時間関数 microtime() が乱数として直接使用され、MD5 の最初の 6 桁が使用されます。が得られます。
#!phpsubstr(md5(print_r(microtime(),true)),0,6);
PHP の microtime() の値は、現在のサーバーの秒数だけでなく、マイクロ秒数も含まれます。マイクロ秒の範囲は 0.000000 ~ です。通常、たとえば、サーバーの時刻は HTTP 戻りヘッダーの DATE フィールドを通じて取得できるため、これらの 1,000,000 個の可能な値を調べるだけで済みます。しかし、ブルート フォースを使用して 1,000,000 のネットワーク リクエストを開始したい場合、ネットワーク リクエストの数は非常に多くなります。しかし、shopex は非常に配慮しており、パスワードを生成する前に microtime() を再度出力します:
#!php$messenger = &$this->system->loadModel('system/messenger');echo microtime()." ";
2. Qihoo 360 の任意のユーザー パスワード変更
直接 MD5 (UNIX タイムスタンプ) )
3. Tuya Kingdom の弱い乱数は、あらゆるユーザーの乗っ取りの脆弱性につながります。テスト POC が添付されています。
パスワードの乱数を取得する問題に関して、私たちは強く主張しています。 Tuo Ge の 11 年の記事「システム時間を使用して Java 乱数を予測どおりに解読する | 空の放蕩心の魂」を参照することをお勧めします。
CmsEasy 最新版暴力的インジェクション (暗号化および復号化の欠陥/アンチインジェクションのバイパス)
弱い擬似乱数はバイパスされます
Espcms v5.6 ブルート フォース インジェクション
Espcms の SQL インジェクションの脆弱性の悪用 ただし、espcms は渡された値を暗号化し、ランダムなキーを持っていることが判明しました。固定乱数プールを持つ弱い疑似乱数であり、攻撃者がグローバル防御ブルート フォースを回避するために使用できるトラバーサル バイパス
Destoon B2B 2014-05-21 最新バージョン。インジェクション (公式デモは再現可能)
use Microtime() は乱数として使用され、予想通り総当たり攻撃が可能です
Apache Harmony の SecureRandom 実装Android 4.4 より前の Java Cryptozoological Architecture (JCA) で使用されていた 6.0M3 とその以前のバージョンには、特に classlib/modules/security/src/main/java/common/org/apache/harmony/ の EngineNextBytes 関数内にセキュリティ上の脆弱性があります。 security/provider/crypto/SHA1PRNG_SecureRandomImpl.java
、ユーザーが乱数を提供しない場合、シードが使用される場合、プログラムはオフセットを正しく調整できず、ランダム シーケンスを生成する PRNG プロセスが予測可能になります。 。
Android SecureRandom の脆弱性の詳細な説明
上記の乱数の基本と脆弱性の例は、攻撃者にいくつかのアイデアを提供することに重点を置いています。ここでは、さらに防御と防止の提案を示します。
ビジネス シナリオでは乱数を使用する必要があり、トークンの生成などで乱数を使用する必要があります。
乱数は次のとおりである必要があります。暴力を避けるのに十分な長さ クラッキング;
目的に応じて乱数が異なるシードを使用するようにします
高度なセキュリティ要件を持つ乱数 (例:暗号技術関連) 禁止された弱い擬似乱数:
時間関数を乱数として使用しないでください (多くのプログラマはタイムスタンプを使用することを好みます) Java: system.currenttimemillis() php : microtime( )
弱い擬似乱数生成器を使用しない Java: java.util.Random PHP: rand() の範囲は小さく、32767 PHP: mt_rand() は欠陥
強力な擬似乱数 CSPRNG (Cryptographically Secure Pseudo-Random Number Generator) に関するさまざまなリファレンス
Platform | CSPRNG |
---|---|
PHP | mcrypt_create_iv, openssl_random_pseudo_bytes |
Java | java.security.SecureRandom |
Dot NET (C#, VB) | System.Security.Cryptography.RNGCryptoServiceProvider |
Ruby | SecureRandom |
Python | os.urandom |
Perl | Math::Random::Secure |
C/C++ (Windows API) | CryptGenRandom |
Any language on GNU/Linux or Unix | Read from /dev/random or /dev/urandom |
6強力な擬似乱数の生成 (独自の実装を開発することはお勧めしません)
高強度の乱数を生成するには、シードとアルゴリズムという 2 つの重要な要素があり、それらを選択する方法がいくつかあります。通常、シードは非常に重要な要素です。たとえば、Random のシードは System.currentTimeMillis() であるため、その乱数は予測可能です。これは、さまざまなコンピューター情報を収集するという考えです。入力時間、メモリ使用状況、ハードディスクの空き容量、IO 遅延、プロセス数、スレッド数およびその他の情報、CPU クロック、主に予測不可能性を実現するために、ほぼランダムなシードを取得します。乱数セキュリティの内容については、PHP 中国語 Web サイト (www.php.cn) をご覧ください。