ホームページ > バックエンド開発 > PHPチュートリアル > 乱数セキュリティについて話しましょう

乱数セキュリティについて話しましょう

PHP中文网
リリース: 2016-06-20 12:27:50
オリジナル
1421 人が閲覧しました


0x00 はじめに

過去 2 回の学校採用面接中に、興味深い現象について友人と話しました。このコースでは、ほとんどの学生は暗号化の基本的な知識さえ持っていませんが、一部の学生は基本的な知識を持っています。

そこで、ここでは簡単な基本的な暗号化の知識についてお話したいと思います。これにはアルゴリズムの実装は含まれませんが、問題を理解しやすくするために一般的な脆弱性シナリオに関連したもので、ちょっとした入門編です。ポイント。

この記事では主に乱数について説明します。乱数は実際には非常に幅広く、暗号技術の基礎とも言えます。

乱数を不適切に使用すると、重大なセキュリティ上の問題が発生する可能性が高く、これらのセキュリティ上の問題は通常、比較的隠蔽されます。

0x01 乱数

概要

乱数はコンピューター アプリケーションで広く使用されており、最もよく知られているアプリケーションは暗号化です。この記事では主に、乱数の使用によって引き起こされる Web セキュリティのリスクについて説明します。

まず乱数について簡単に見てみましょう



分類

乱数は分類されています真の乱数と擬似乱数として、私たちのプログラムでは基本的に擬似乱数を使用しますが、擬似乱数は強い擬似乱数と弱い擬似乱数に分けられます。

  1. 真の乱数は、コイン、サイコロ、ホイールを投げる、電子部品からのノイズ、核分裂などを使用するなどの物理実験を通じて取得されます。

  2. 特定のアルゴリズムとシードを通じて取得された擬似乱数。このソフトウェアは、疑似乱数

    1. 強力な疑似乱数 、予測不可能な乱数

    2. 弱い擬似乱数、予測しやすい乱数

特徴

乱数には以下の 3 つの特徴があります。 🎜 >

  1. ランダム性: 統計的な偏差はなく、完全にカオスなシーケンスです

  2. 予測不可能性 :過去の配列から次に出現する数字を推測することはできない

  3. 非再現性 :配列そのものを保存しない限り、同じ配列を再現することはできないたとえば、シーケンス

は、乱数の分類に関連しています。たとえば、弱い擬似乱数は乱数を満たす必要があるだけですが、強い乱数は乱数と予測不可能性、つまり真のランダムを満たす必要があります。数値は 3 つの特性を同時に満たす必要があります。

セキュリティ上の問題を引き起こす重要なポイントは、予測不可能性です。

擬似乱数の生成

私たちが通常ソフトウェアやアプリケーションに実装するのは擬似乱数であるため、この記事の焦点は擬似乱数です。

擬似乱数生成の実装は、一般的に

アルゴリズム + シード です。

特定の擬似乱数生成器 PRNG には通常次のものが含まれます:

  1. 線形合同法

  2. 一方向ハッシュ関数法

  3. Cryptmethod

  4. ANSI C言語の有名なrandライブラリやJavaのjava.util.Randomクラスなどの剰余メソッド、どちらも線形合同法を使用して乱数を生成します。

    アプリケーション シナリオ
乱数のアプリケーション シナリオは比較的広範囲にわたります。以下は、乱数の一般的なアプリケーション シナリオです。

検証コード生成

  • 抽選イベント

  • UUID 生成

  • SessionID 生成

  • トークン生成

  • CSRF トークン

    • パスワード トークンの取得

    • ゲーム (ランダム要素の生成)

  • シャッフル

    • 特定の形状が出現するテトリス シーケンス

    • ゲーム爆発物装置

    • パスワード適用シナリオ

  • 生成キー: 対称パスワード、メッセージ認証

    • キーペアの生成: 公開キー暗号、デジタル署名

    • IV の生成: ブロック暗号の CBC、CFB、および OFB モード

    • ノンスの生成: リプレイ攻撃に対する防御に使用されます。ブロック暗号の CTR モード

    • ソルトの生成: パスワードベースのパスワード PBE などに使用されます。 🎜>

    • 0x02 乱数のセキュリティ

      他の暗号技術と比較すると、乱数はあまり注目されていませんが、暗号技術やコンピューター アプリケーションでは乱数は重要です。非常に重要ですが、乱数を誤って使用すると、一連のセキュリティ上の問題が発生する可能性があります。
    乱数のセキュリティ リスク

乱数によって引き起こされるセキュリティ上の問題は、一般に 2 種類あります

乱数を使用する必要があり、開発者は乱数を使用する必要があります。 not

乱数

は使用されませんでした。

  1. は強力な擬似乱数を使用する必要がありますが、開発者 は弱い擬似乱数 を使用しました。

  2. 最初のケースは、簡単に言えば、乱数が必要であるということですが、開発者は乱数を使用せず、定数を指定しました。もちろん、sb は乱数を使用していないと憤慨する人も多いでしょう。ただし、まだたくさんあることを無視しないでください。主なシナリオは 2 つあります。 開発者には基本的な常識が欠如しており、乱数の使い方を知りません。

    一部のアプリケーション シナリオとフレームワークには、インターフェイスのドキュメントが不完全であるか、開発者がそれを注意深く読んでいません。

    たとえば、パスワードを取得するためのトークンには擬似乱数が必要ですが、多くの企業はユーザー名に基づいてトークンを直接生成します。

    たとえば、OAuth2.0 では、サードパーティがCSRF 攻撃を防ぐには、状態パラメーターを CSRF トークンとして渡す必要があります。CSRF 攻撃の場合、多くの開発者はこのパラメーターをまったく使用しないか、固定値を渡します。認証者はこの値のビジネス レベルの有効性を検証できないため、OAuth CSRF 攻撃が発生します。

    2 番目のケースの主な違いは、ほとんど (すべて?) 言語の API ドキュメントの基本ライブラリ (一般的に使用されるライブラリ) のランダム ライブラリです。弱い擬似ランダムなので、多くの開発者は当然それを直接使用します。しかし、最も重要かつ致命的なことは、弱い擬似乱数は暗号化では使用できないということです。

    これはまだ最初の状況のパスワード取得シナリオですが、トークンの生成に関して、多くの開発者はタイムスタンプを乱数として使用します (md5 (タイムスタンプ)、md5 (タイムスタンプ + ユーザー名))。予測可能であるため、簡単に推測できます。 予測不可能性は、弱い擬似乱数と強い擬似乱数を区別するための重要な指標です

    もちろん、上記 2 つの状況に加えて、通常はまれですが、例外ではありません。

    1. 種子の漏洩、アルゴリズム 多くの場合、シードが漏洩した場合、乱数が漏洩したことを意味します。

    2. 乱数プールが不足しています。厳密に言えば、これも弱い擬似乱数です。乱数プールが不十分であるため、実際には乱数が予測可能になり、攻撃者が直接総当たり攻撃を行うことができるからです。

    脆弱性の例

    wooyun には非常に興味深い脆弱性が多数あり、それらはすべて乱数に関連しています。

    追伸: 以下の例は基本的に wooyun の脆弱性の例からのものです。侵害がある場合は、削除のためにご連絡ください。

    1. 乱数の代わりに乱数を使用する必要があります

    Oauth2.0 のこの問題は、wooyun の例に挙げたもの以外にも、実際に多くのメーカーで発生しています。 。

    Oauth2.0 の state パラメーターでは、サードパーティ アプリケーションの開発者が CSRF トークン (乱数) を渡す必要があります。これが渡されない場合、または渡されたものが乱数でない場合は、次のような問題が発生します。 CSRF による任意のアカウントへのログイン:

    1. Vipshop アカウントに関連する脆弱性により、CSRF を通じて任意のアカウントにログインできます

    2. Renren-Baidu OAuth 2.0 redirect_uir CSRF 脆弱性

    2. 弱い擬似乱数を使用する

    1) パスワードの取得

    多くのパスワード取得シナリオでは、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 乱数を予測どおりに解読する | 空の放蕩心の魂」を参照することをお勧めします。

    2) 他の乱数検証シナリオ

    • 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 の脆弱性の詳細な説明

    セキュリティに関する提案

    上記の乱数の基本と脆弱性の例は、攻撃者にいくつかのアイデアを提供することに重点を置いています。ここでは、さらに防御と防止の提案を示します。

    1. ビジネス シナリオでは乱数を使用する必要があり、トークンの生成などで乱数を使用する必要があります。

    2. 乱数は次のとおりである必要があります。暴力を避けるのに十分な長さ クラッキング;

    3. 目的に応じて乱数が異なるシードを使用するようにします

    4. 高度なセキュリティ要件を持つ乱数 (例:暗号技術関連) 禁止された弱い擬似乱数:

      1. 時間関数を乱数として使用しないでください (多くのプログラマはタイムスタンプを使用することを好みます) Java: system.currenttimemillis() php : microtime( )

      2. 弱い擬似乱数生成器を使用しない Java: java.util.Random PHP: rand() の範囲は小さく、32767 PHP: mt_rand() は欠陥

    5. 強力な擬似乱数 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) をご覧ください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート