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

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

WBOY
リリース: 2016-06-23 13:03:53
オリジナル
1507 人が閲覧しました

0x00 はじめに

過去 2 年間の学校の採用面接では、ほとんどの生徒が、ある程度の侵入スキルを持っていたとしても、基本的な暗号化の知識さえ持っていませんでした。

そこで、ここでは、アルゴリズムの実装を含まない、簡単な基​​本的な暗号化の知識についてお話したいと思います。これは、問題を理解しやすくするための一般的な脆弱性シナリオに関連したものであり、ちょっとした出発点です。

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

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

0x01 乱数

概要

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

まずは乱数について簡単に理解しましょう

分類

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

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

疑似乱数は、特定のアルゴリズムとシードを通じて取得されます。ソフトウェアは擬似乱数を実装しています

強い擬似乱数、予測が難しい乱数

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

特徴

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

ランダム性 : 統計的偏差がなく、完全にカオスな数列です

予測不可能性 : 過去の数列から次に出現する数字を推測することはできません

非再現性 : 数列自体を保存しない限り、同じ数列を再現することはできませんシーケンス

乱数の特性は乱数の分類と一定の関係があります。たとえば、弱い疑似乱数は乱数を満たす必要があるだけですが、強い乱数は乱数と予測不可能性を満たす必要があり、真の乱数は乱数を満たす必要があります。 3つの特性を同時に満たします。

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

擬似乱数の生成

通常のソフトウェアとアプリケーションは擬似乱数を実装しているため、この記事の焦点は擬似乱数です。

疑似乱数生成の実装は、一般にアルゴリズム + シードです。

具体的な擬似乱数生成器 PRNG には通常次のものが含まれます:

線形合同法

一方向ハッシュ関数法

暗号法

ANSI X9.17

より一般的に使用されるのは、次のような線形合同法です。私たちがよく知っている C 言語の rand ライブラリと Java の java.util.Random クラスは、どちらも線形合同法を使用して乱数を生成します。

アプリケーションシナリオ

乱数のアプリケーションシナリオは比較的広範囲にわたります:

検証コード生成

宝くじイベント

UUID生成

セッションID生成

トークン生成

CSRFトークン

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

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

シャッフル

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

ゲーム爆発装置

パスワード適用シナリオ

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

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

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

nonce の生成: ブロック暗号の CTR モードに対する防御用

ソルトの生成: パスワード用

0x02 乱数のセキュリティ

他の暗号技術に比べて乱数はあまり注目されていませんが、乱数は暗号技術やコンピュータアプリケーションにおいて非常に重要であり、乱数の誤った使用につながります。一連のセキュリティ問題。

乱数のセキュリティリスク

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

乱数を使用する必要がありますが、開発者は乱数を使用しませんでした。

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

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

開発者には基本的な常識が欠如しており、乱数の使用方法がわかりません。

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

たとえば、パスワードを取得するためのトークンには擬似乱数が必要です。

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

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

トークンの生成に関しては、多くの開発者がタイムスタンプを乱数 (md5 (タイムスタンプ)、md5 (タイムスタンプ + ユーザー名)) として使用しますが、タイムスタンプは予測可能で簡単です。推測する。予測不可能性は、弱い擬似乱数と強い擬似乱数を区別する重要な指標です。

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

シードの漏洩、アルゴリズムは公開されることが多く、シードが漏洩した場合、それは乱数に相当します 番号が漏洩しました

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

脆弱性の例

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

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

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

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

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

Vipshop アカウント 関連する脆弱性は、csrf 経由で任意のアカウントにログインするために使用される可能性があります

Renren-Baidu OAuth 2.0 redirect_uir CSRF 脆弱性

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

1) パスワードの取得

多数パスワード取得シナリオはユーザーのメールに送信されます。URL の途中にトークンが含まれており、このトークンを推測すると、他のユーザーのパスワードを取得できます。

1. Shopex 4.8.5 のパスワード取得で新しく生成されるパスワードに予測可能な脆弱性

時間関数 microtime() が乱数として直接使用され、MD5 の最初の 6 桁が取得されます。

substr(md5(print_r(microtime(),true)),0,6); 
ログイン後にコピー

PHP の microtime() の値には、現在のサーバーの秒数だけでなく、マイクロ秒数も含まれます。マイクロ秒の範囲は、一般的に、HTTP で返すことができます。ヘッダーの DATE フィールドを取得する必要があるため、これらの 1,000,000 個の可能な値を反復処理するだけで済みます。しかし、ブルート フォースを使用して 1,000,000 のネットワーク リクエストを開始したい場合、ネットワーク リクエストの数は非常に多くなります。しかし、shopex は非常に配慮しており、パスワードを生成する前に microtime() を再度出力します。

$messenger = &$this->system->loadModel('system/messenger');echo microtime()."<br/>"; 
ログイン後にコピー

2. Qihoo 360 の任意のユーザーのパスワード変更

直接 MD5 (unix タイムスタンプ)

3. Tuya Kingdom の弱い乱数により、任意のユーザーがハイジャックされる脆弱性が発生します。テスト POC が添付されています

パスワードの乱数を取得する問題については、Tuo Ge の 11 年間の記事「システム時間を使用して Java 乱数を予測可能にクラックする | 空の放蕩心の魂」を参照することを強くお勧めします

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

CmsEasy 最新バージョン ブルート フォース インジェクション (暗号化および復号化の欠陥/アンチインジェクションのバイパス)

弱い疑似乱数はバイパスされます

Espcms v5.6 ブルート フォース インジェクション

SQL インジェクションの悪用Espcms の脆弱性を悪用すると、espcms は送信される値を暗号化し、ランダムなキーを持っていることが判明しましたが、これは固定乱数プールを備えた弱い擬似乱数であり、攻撃者によって通過およびバイパスされる可能性があります

Destoon B2B 2014-05-21 最新バージョンは、グローバルな防御をバイパスします。 ブルート フォース インジェクション (公式デモは再現可能)

microtime() を乱数として使用し、予想どおりブルート フォースでクラックされる可能性があります

Apache Harmony 6.0M3 とその以前のバージョンは、で使用されていますAndroid 4.4 以前のバージョンの Java Cryptozoology Architecture (JCA) には、SecureRandom 実装にセキュリティ上の脆弱性があり、特に classlib/modules/security/src/main/java/common/org/apache/ の EngineNextBytes 関数にあります。 Harmony/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 (暗号的に安全で信頼できる擬似乱数生成器) 安全な擬似乱数生成器に関するさまざまなリファレンス

6. 強力な擬似乱数の生成 (独自の実装を開発することはお勧めしません)

高強度の乱数を生成するには、シードとアルゴリズムという 2 つの重要な要素があります。多くのアルゴリズムが存在する可能性があり、通常、シードをどのように選択するかが非常に重要な要素になります。 たとえば、Random のシードは System.currentTimeMillis() であるため、その乱数は予測可能であり、弱い擬似乱数です。

強力な擬似乱数を生成するというアイデア: さまざまなコンピューター情報、キーボード入力時間、メモリ使用状況、ハードディスクの空き容量、IO 遅延、プロセス数、スレッド数などの情報、CPU クロックを収集し、主に予測不可能性を実現するために、ほぼランダムな数のシードを取得します。

0x03 添付

参考資料:

http://www.inbreak.net/archives/349

http://drops.wooyun.org/papers/1066

「White Hat Talks about Web Security」

「図解暗号技術」

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