PHPSESSID経由でmt_rand sidを受け取る
PHPSESSIDは次のように生成されます。
md5(クライアントIP。タイムスタンプ。マイクロ秒1。php_combined_lcg())
- クライアントIPは攻撃者に知られています
- タイムスタンプが既知(Webサーバー応答の日付ヘッダー)
- マイクロ秒1-0〜1,000,000の値
- php_combined_lcg()-値の例:0.12345678
php_combined_lcg()を生成するには、2つのsidが使用されます。
S1 =タイムスタンプXOR(マイクロ秒2 << 11)
S2 = pid XOR(マイクロ秒3 << 11)
- タイムスタンプは同じです
- マイクロ秒2は、最初の測定値(マイクロ秒1)よりも0〜3大きい
- pid-現在のプロセスのプロセスID(0-32768)
- マイクロ秒3 1-4マイクロ秒2
最高のエントロピーはマイクロ秒単位ですが、2つの手法を使用すると、マイクロ秒のエントロピーを大幅に減らすことができます。
サーバーとクライアントの同期
この手法のポイントは、リクエストのペアを順番に送信して、Dateヘッダーの2番目のヘッダーがいつ変わるかを判断することです。
HTTP / 1.1 200 OK
日付:2012年8月8日水曜日06:05:14 GMT
...
HTTP / 1.1 200 OK
日付:2012年8月8日水曜日06:05:15 GMT
これが発生した場合、リクエスト間でマイクロ秒がリセットされます。 動的な遅延を伴うリクエストを送信することにより、ローカルマイクロ秒値をサーバー値と同期できます。
双子のリクエスト
原理はこれです。 2つのリクエストを次々に送信します。1つ目はパスワードを自分自身にリセットすることで、2つ目は管理者パスワードをリセットすることです。 マイクロ秒の差はごくわずかです。
したがって、md5 PHPSESSIDブルートは、マイクロ秒、マイクロ秒の後続の測定のためのデルタ、およびpidを選択することにあります。 pidに関しては、著者はserver-statusのようなApacheのことを忘れてしまいました。これは、とりわけ、クライアントリクエストを処理するプロセスの「pid」を示し、非常に便利です。
Brutusの場合、PasswordsProのモジュールは元々書かれていましたが、このアプローチではデルタマイクロ秒の相関を考慮することは不可能なので、全範囲をブルートしなければなりませんでした。 速度は1秒あたり約1200万シードでした。
その後、 特別なプログラムが作成されました。
速度-毎秒約1600万シード、SID計算-1時間未満(3.2 GHz x 4 i5)。
pidとphp_combined_lcg()の値を受け取ったら、次のように生成されるmt_randのシードを計算できます。
(タイムスタンプx pid)XOR(106 x php_combined_lcg())
さらに、 php_combined_lcg()は uniqid関数の追加エントロピーとして使用されます(2番目のパラメーター= trueで呼び出された場合)。
したがって、Webアプリケーションが標準のPHPセッションを使用する場合、mt_rand()、rand()、uniqid()を予測できます。
乱数の1つを出力してmt_rand sidを取得する
mt_rand()のsid値は2 ^ 32の整数です。 乱数の出力がある場合、シードを選択することができます。これは、実際にはレインボーテーブルではかなり可能です。これにより、約10分でシードを見つけることができます。
テーブルの生成、SIDおよび既製のテーブルの選択のシナリオはこちらです: http : //www.gat3way.eu/poc/mtrt/
コードで何を探すべきですか?
mt_rand()、rand()、uniqid()、shuffle()、lcg_value()などの呼び出し。 保護の主な方法:
- MySQL関数RAND()-高い確率で予測することもできます。
- スホシンパッチ-デフォルトでは、関数mt_srand、srandにパッチを適用しません。 Suhosinを拡張機能として個別にインストールすると、保護が提供されます。
- / dev / urandom-鉄の方法。
アーセニー・ロイトフ
ティムール・ユヌソフ
ドミトリー・ナギビン