前に述べた 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) ; 五島平野}
ただし、この時点でまだ配列変数を登録していても、この変数がすでに 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 を見てみましょう:
を見てください。
|