ホームページ >バックエンド開発 >PHPチュートリアル >PHP-5.3.9 リモートで任意のコードが実行される脆弱性 (CVE-2012-0830) 詳細説明_PHP チュートリアル

PHP-5.3.9 リモートで任意のコードが実行される脆弱性 (CVE-2012-0830) 詳細説明_PHP チュートリアル

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

前に述べた PHP ハッシュ衝突の Ddos 脆弱性を覚えていますか? 当初、開発チームが提示した修復計画では、max_input_vars を超えるとエラー (E_ERROR) が報告され、その後、PHP がエラーで終了することになりました。より正確に言うと、この問題を軽量な方法で解決するために、この問題を少し改良し、max_input_vars を超えた場合に警告 (E_WARNING) を発行するように変更し、宛先配列に追加しなくなりましたが、プロセスは続行されます。 5.3.9 をリリースしました。

この新しい修正には善意が含まれていますが、もともと Stefan Esser によって発見された深刻な問題 (5.3.10 で修正) が導入されています。(5.3.9) (php_register_variable_ex) より前の最終修正を参照してください。 ):

コードは次のとおりです コードをコピー

しながら (1) {

if (zend_symtable_find(symtable1,scape_index,index_len + 1,(void **)&gpc_element_p) == 失敗

|| Z_TYPE_PP(gpc_element_p) != IS_ARRAY) { //(3)

if (zend_hash_num_elements(symtable1)

if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "入力変数が %ld を超えました。...", PG(max_input_vars));

}

MAKE_STD_ZVAL(gpc_element);

array_init(gpc_element);

zend_symtable_update(symtable1,scape_index,index_len + 1,&gpc_element,sizeof(zval *),(void **)&gpc_element_p);

}

//......

}

symtable1 = Z_ARRVAL_PP(gpc_element_p) // (2)

; 五島平野

}

  • この時点で配列変数を登録し (GET の a[]=2 と同様)、この変数がたまたま max_input_vars 番目の変数である場合、警告 (1) がトリガーされ、その時点ではすべてが正常であることに注意してください。今回は。

    ただし、この時点でまだ配列変数を登録していても、この変数がすでに max_input_vars + 1 番目の変数である場合、この時点では gpc_element_p は初期化されていないポインタになり、ロジックは引き続き実行されるため、また、位置 (2) では、初期化されていないポインタが逆参照されます。

    したがって、この時点で、この機能を使用して 5.3.9 で Ddos を実行できます。サーバーでコア ダンプが有効になっている場合、その効果は非常に明白になります。

    ただし、この問題はさらに深刻な問題を引き起こす可能性もあります:

    最外層にループがあり、a[b]=2のようなペアを登録すると、最初にa[]が挿入されたときにループが2回実行されます。 . 、 2 回目に b を a[] に挿入します。次に、目的の要素が宛先配列に見つからない場合、** または要素が配列でない場合** にも注意してください。これはそのまま(2)の処理に任せることに繋がるので問題が発生します

    次のような POST 文字列の場合 (デフォルトの max_input_vars は 1000):

    1=1&1=2&..........&999=1&x="私は悪意のある文字列です"&x[0]=

    何が起こるでしょうか?


    それを段階的に説明しましょう:

    1. 1から999までは問題なく、すべて正常に挿入されます

    2. x は 1000 要素なので、警告がトリガーされますが、問題はありません、x が挿入されます

    3. x[0]が挿入されると、(3)の文はArraryではないと判断してif本体に入りますが、この時点で(4)の文が失敗するので、最終的に(2)の処理に進みます

    4. この時点で、gpc_element_p は、私たちが偽造した文字列である x を指します...

    ここで、主要なデータ構造 zval を見てみましょう:

    コードは次のとおりですstruct _zval_struct {
    コードをコピー

    /* 変数情報 */

    zvalue_value 値 /* 値 */

    zend_uint refcount__gc;

    zend_uchar タイプ; /* アクティブなタイプ */

    zend_uchar is_ref__gc;

    };<

    次に、zvalue_value:

    を見てください。

    コードは次のとおりですtypedef Union _zvalue_value {


    zvalue_value は共用体なので、構築する文字列領域のメモリはハッシュテーブル構造として扱われます:

    コードをコピー

    long lval; /* 長い値 */

    double dval /* double 値 */

    構造体{

    char *val;

    int len;

    } ストラ;

    HashTable *ht; /* ハッシュ テーブルの値 */

    zend_object_value obj;

    } zvalue_value;<

    コードは次のとおりです コードをコピー

    typedef struct _hashtable {

    uint nTableSize;

    uint nTableMask;

    uint nNumOfElements;

    ulong nNextFreeElement;

    Bucket *pInternalPointer; /* 要素の走査に使用されます */

    バケット *pListHead;

    バケット *pListTail;

    バケット **arBuckets;

    dtor_func_t pDestructor; // これに注意してください

    zend_bool 永続的;

    unsigned char nApplyCount;

    zend_bool bApplyProtection;

    #if ZEND_DEBUG

    一貫性がありません;

    #endif

    }ハッシュテーブル;<


    Hashtable 構造には pDestructor があり、このポインターは関数を指します。Hashtable 内にクリアする必要がある要素がある場合、それが呼び出されます。

    言い換えれば、任意のアドレス (pDestructor) を設定し、PHP にそれを呼び出させることができます (要素の削除を誘導します)。

  • http://www.bkjia.com/PHPjc/629666.html

    www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/629666.html技術記事前に述べた PHP Hash Collisions Ddos の脆弱性を覚えていますか? 当初、開発チームが提示した修復計画は、max_input_vars を超えた場合にエラー (E_ERROR) を報告することでした。これにより、P... が発生します。
    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。