ホームページ  >  記事  >  バックエンド開発  >  PHP キャスト タイプとリモート管理プラグインの危険性_PHP チュートリアル

PHP キャスト タイプとリモート管理プラグインの危険性_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:32:56798ブラウズ

PHP の型強制は C の型強制と非常によく似ています。変換される変数の前に、かっこで囲まれたターゲットの型が置かれます。

許可されているキャストは次のとおりです:

(int),(integer) - 整数型に変換します

(bool),(boolean) - ブール型に変換します

(float),(double),(real) - 浮動小数点型に変換します

(string) - 文字列に変換します

(配列) - 配列に変換します

(オブジェクト) - オブジェクトに変換します

括弧内ではスペースとタブを使用できることに注意してください

settype(混合変数、文字列型)を使って強制変換することもできます

リモート管理プラグインは、WordPress サイト管理者にとって非常に人気のあるツールで、ユーザーは最新リリースへの更新やプラグインのインストールなど、複数のサイトで同じ操作を同時に実行できます。ただし、これらの操作を実装するには、クライアント プラグインはリモート ユーザーに重要な権限を付与する必要があります。したがって、管理サーバーとクライアント プラグイン間の通信が安全であり、攻撃者によって偽造できないことを保証することが重要です。この記事では、利用可能なプラグインをいくつか取り上げますが、その弱点により、攻撃者がプラグインを実行しているサイトを完全に侵害する可能性があります。

WP、InfiniteWP、CMS Commanderを管理する

これら 3 つのサービスは同じ基本的なクライアント プラグイン コードを持っているため (視覚的には、もともと ManageWp によって実装され、その後、他の 2 つがそれを調整したものです)、そのため、それらはすべてシグネチャ バイパスの脆弱性を抱えており、リモートでコードが実行される可能性があります。

管理サーバーは、ユーザーに管理者の資格情報 [MAC] の提供を要求するのではなく、クライアント プラグインの秘密キーを登録して、各メッセージのメッセージ認証コードを計算します。ここでは、通常、それをハードウェアの MAC アドレスとして認識します。はメッセージ認証コードです]。メッセージ ダイジェストは、メッセージが共有秘密キーを使用してメッセージ ダイジェスト アルゴリズムを通過するときに生成されます。 MAC はメッセージに添付されて送信され、受信後、受信側は共有秘密キーを使用して受信メッセージを計算し、MAC2 を生成し、それを MAC1 と比較します。メッセージ ダイジェストは、メッセージの信頼性と完全性を検証するために使用されます [暗号化を学習した学生は知っておくべきです]。しかし、これら 3 つのサービスのクライアント プラグインの実装上の欠陥が原因です。重大な抜け穴に。

helper.class.php によって認証された受信メッセージは次のようになります:

// $signature はメッセージとともに送信される MAC です // $data はメッセージの一部です if (md5($data . $this->get_random_signature()) == $signature) { // 有効なメッセージ }

非厳密な等号を使用すると、比較の前に型の「スプーフィング」[型変換] が発生します。 md5() 関数の出力は常に文字列ですが、$signature が整数に変更されると、比較中に発生する型変換により、一致する MAC が簡単に偽造される可能性があります。たとえば、実際の MAC が「0」または数字以外の文字で始まる場合は、0 が一致し、「1xxx」の場合は整数 1 が一致します。 [これは実際には PHP の機能であり、もちろん他の言語にもあります。文字列と数値が非厳密に等しいかどうかを比較する場合、最初の文字が数値の場合は、対応する整数に変換されます。比較用の場合 0 ~ 9 以外の文字の場合は、0 として扱われます。 php.net からのメモ: 数値と文字列を比較する場合、または数値の内容を含む文字列を比較する場合、文字列は に変換されます。数値と比較は数値に基づいて行われます。

文字列を数値に変換します:

文字列を数値として扱う場合、結果と型は次のようになります。

文字列に「.」、「e」、「E」が含まれず、その数値が整数の範囲内(PHP_INT_MAXで定義されている)の場合、文字列は整数として扱われます。それ以外の場合はすべて、値は浮動小数点数として扱われます。

文字列の先頭がその値を決定します。文字列が有効な数値で始まる場合は、その数値が使用されます。それ以外の場合、その値は 0 (ゼロ) です。有効な値は、オプションの符号、その後に続く 1 つ以上の数字 (小数点を含む場合もあります)、およびオプションの指数部分で構成されます。指数部は、「e」または「E」とそれに続く 1 つ以上の数字で構成されます。

// $signature はメッセージと一緒に送信された MAC です

// $data はメッセージの一部です

if (md5($data . $this->get_random_signature()) == $signature) {

// 有効なメッセージ }

残念ながら、攻撃者は署名として整数を提供する可能性があります。 init.php では、受信リクエストはbase64_decode() を使用してデコードされ、結果が逆シリアル化されます。 Unserialize() を使用すると、入力データの種類を制御できることを意味します。 偽のシリアル化メッセージは次のとおりです。

a:4:{s:9:"署名";i:0;s:2:"id";i:100000;s:6:"アクション";s:16:"execute_php_code";s:6: "params";a:2:{s:8:"ユーザー名";s:5:"管理者";s:4:"コード";s:25:"exec('touch /tmp/owned');" ;}}

このメッセージは整数 0 を署名として使用し、プラグインが提供するexecute_php_codeを使用して任意のPHPコードを実行します。

$signature = 0; // $data はメッセージ ID と連結されたアクションです $data = 'execute_php_code' . if (md5($data . $this->get_random_signature()) == $signature) { / / / md5() の出力が数字で始まらない場合の有効なメッセージ }

この偽造された例は、直接使用することはできません。まず、ID のキーの値は、以前の正規のメッセージの値よりも大きい必要があります (増加したメッセージ ID は、現在、リクエストの偽造とリプレイの両方の攻撃を防ぐために使用されています)。これは、CSRF (クロスサイト リクエスト フォージェリ) を思い出させます。以下に中間者攻撃がありますか?)、次に、これら 2 つの要件は、ブルート フォース クラッキングによって突破できます。

i が 100,000 から 100,500 の場合: j が 0 から 9 の場合: ID i と署名 j を使用してリクエストを送信します

上記の疑似コードは、大きな ID 値を持つ偽のメッセージを送信しようとし、ID ごとに 10 回の個別のデジタル指紋照合を実行します [前述したように、文字列の場合、比較中に照合できる数値は 1 つだけです。ここでは 0 ~ 9 であるため、あらゆる状況に遭遇する可能性があります]。

この欠陥は、合同演算子 [===] を使用し、受信したフィンガープリントを確認することで修正できます。これらのプラグイン サービスは、厳密な合同演算子を使用することで修正されています [php.net 命令: a===b、その後、a と b は等しい値と型を持ちます。型が発生した場合、変換後に決定します。値が等しいかどうか]。

他にもいくつか問題がありますが、まだ対策は講じられていません。まず第一に、このアプローチには弱点があります [$data にキーを追加してハッシュする]。HMAC [ハッシュベースのメッセージ認証コード。キーとメッセージを入力として受け取り、メッセージ ダイジェストを出力として生成します] を使用する必要があります。次に、署名の作成には、操作のアクション ID とメッセージ ID のみが使用されます。これは、アクティブな攻撃者がメッセージ内のパラメーターを変更でき、署名が引き続き有効であることを意味します (任意のコードを実行するためにexecute_php_codeメッセージを変更するなど)。保護のために、MAC にはメッセージ全体が含まれている必要があります。

[MD5 ベースのメッセージ ダイジェストはフォールバックであることに注意してください。可能であれば、これらのプラグインは openssl_verify(); ***2014 年に発表された Openssl 1.0.f のハートブリード脆弱性は、世紀レベルの脆弱性として知られています。 *]

ワーピット

Worpit もリモート管理サービスですが、これはスクラッチから構築されたクライアント プラグインを使用しており、攻撃者が管理者権限でログインできるキャスト脆弱性もあります。

このプラグインは、Woprit のみを使用して、システムによって構成できる一時的なトークン値を配信する、リモート管理者ログインの方法を提供します。このプラグインは、リクエストで提供されたトークン値がデータベースに保存されている値と一致するかどうかをチェックします。

if ( $_GET['token'] != $oWpHelper->getTransient( 'worpit_login_token' ) ) { die( 'WorpitError: 無効なトークン' }

トークンは一度使用されるとデータベースから削除されます。これは、ほとんどの場合、データベースにトークンが存在しないことを意味します。したがって、getTransient() メソッドを呼び出すと false が返される場合があります。厳密ではない比較は、文字列 0 などの「偽の値」が有効なトークンとして扱われることを意味します。管理者としてログインした URL の例:

このトークンは一度使用されるとデータベースから削除されます。つまり、ほとんどの場合、データベースにはトークンが存在しません。したがって、getTransient() メソッドの呼び出しは false を返す可能性があります。非厳密な比較も使用されます。つまり、文字列 0 などの false に相当する値は有効なトークンとして扱われます。管理者としてのログインの例: http://victim/?worpit_api=1&m=login&token =0

この時点で、サイトは攻撃者によって制御されており、攻撃者は悪意のあるプラグインをインストールしたり、既存のプラグインを変更したりする権限を持っています。

ここでの修正は、!== を使用し、他のチェックを行ってデータベースから取得することです。

結論:

ユーザー入力が予期したタイプであることを常に忘れずに確認し、認証トークンのチェックなど、セキュリティが重要な関数では厳密な比較を使用してください。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/752677.html技術記事 PHP での型キャストは C とよく似ており、変換される変数の前にかっこで囲まれたターゲットの型が置かれます。 許可されるキャストは次のとおりです: (int)、(integer) - 整数に変換します...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。