web-dev-qa-db-ja.com

アレイインジェクションは脆弱性ですか?適切な用語は何ですか?

侵入テストをしているとき、HTTP GETパラメータを使用して1次元または多次元の配列を挿入すると、PHPスクリプトの望ましくない動作が発生することがあります。

可能な可用性リスク

これは、特にPHPスクリプトが(深い)多次元配列を再帰的にループしていて、実行時間に上限がないか高い場合に、多次元配列の注入が発生する場合に、可用性リスクを引き起こす可能性があります。これはリソースの枯渇を引き起こす可能性があるためです実際には、全体が$_GET配列はループされ、ある種のフィルタリングまたは検証が適用されます。


この動作に関する質問

  1. そのような脆弱性の適切な用語は何ですか? 「アレイ注入」?
  2. これはどの脆弱性カテゴリに属しますか(OWASPトップ10またはCWEリストなど)?
  3. これは、可用性リスク以外に、脆弱性と見なされますか?
  4. これが悪用される可能性のある良いシナリオは何ですか?

行動の例

入力:(パラメータとして文字列を期待)

/search.php?query=test

結果:(PHPの$_GET

[query] => test

入力:(挿入された配列)

/search.php?query[]=test

結果:(PHPの$_GET

[query] => Array
(
    [0] => test
)

入力:(注入された多次元配列)

/search.php?query[][][][]=test

結果:(PHPの$_GET

[query] => Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [0] => test
                        )
                )
        )
)
4
Bob Ortiz

そのような脆弱性の適切な用語は何ですか? 「アレイ注入」?

これはどの脆弱性カテゴリに属しますか(OWASPトップ> 10またはCWEリストなど)?

これは " parameter tampering "と呼ばれ、 PHP開発者 、OWASPによってそのように呼ばれており、親は CWE-371 である、例えばパラメータがインジェクションSQLステートメントを含む場合、SQLインジェクションになります。あなたがしていることは、悪影響を生み出すために入力を操作(改ざん)することだけです。

これは、可用性リスク以外に、脆弱性と見なされますか?

脆弱性は、サーバーが 入力のサニタイズに失敗することです

これが悪用される可能性のある良いシナリオは何ですか?

これはアプリケーション自体に依存します。さまざまな状況で何が起こるか、または何が起こるかを確認するために、入力の操作を続ける必要があります。たとえば、改ざん内にネストされたコマンドを挿入してみましたか?例えば。:

/search.php?query[() { example;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/shadow"]=test

基盤となるアプリケーションを理解しないと、何が脆弱かを判別するのは困難です。入力が検証されないという事実は、改ざんされたデータにサーバーが応答できるようにするために、注入するあらゆる種類の事柄をテストできるはずです。大量のデータを挿入して、スタック/バッファ/ヒープオーバーフローをトリガーできるかどうかを確認できます。いくつか試してみることができますが、最初のアプリケーションの機能を知らなくても、これは推測ゲームになります

3
munkeyoto

HTTPパラメータ汚染 という用語が最適だと思います。このタイプの汚染は通常、同じリクエストで異なる値を使用して同じパラメータを複数回送信します。これにより、パラメーターは値の配列として扱われ、パラメーター名は配列名として この記事 で説明されています。 Webサーバーとプログラミング言語が単一の値と比較してこれらの配列を処理する方法は、このバグクラスが利用する方法です。

例では、パラメーターを繰り返す方法が異なりますが、同じ名前の配列が同様に発生しますが、fault injectiontype confusionなどの他の用語と比較すると、より適切に思えます。

このタイプの汚染は通常、未定義の動作を悪用しますが、あなたが提供した例はそうではありません。それらは、配列を処理するための定義された動作を引き起こします。これにより、アプリケーションのフローを変更するために使用される可能性のある例外がトリガーされる場合があります。たとえば、承認チェックでセッションが変更される前にエラーが発生し、特権の昇格が発生します。

7
wireghoul

このように_$_GET_で配列を使用できること自体は、セキュリティ上の脆弱性ではありません。 DoSベクトルは私には無視できるようですが、これを使用するコードによって実際に増幅される可能性があります。

ただし、あなたが提供した例はこの機能の最も重要な部分を逃しました(攻撃者の観点から):この方法でGETおよびPOSTパラメータで通常の配列を渡すことだけが可能ではありませんだけでなく、連想配列。実際、PHPは2つを区別しません。

PHP配列は、整数キーと文字列キーを同時に含むことができます。PHPは、インデックス付き配列と連想配列を区別しません。 – PHP:配列-マニュアル

これは、クライアントが次のようなPOSTパラメータを提供する場合を意味します。

_<input type="text" name="pass[pass1]" value="Password 1">
<input type="text" name="pass[pass2]" value="Password 2">
_

_$_POST_/_$_GET_は次のようになります。

_$_POST = array(
    ...
    'pass' => array(
        'pass1' => 'Password 1',
        'pass2' => 'Password 2', 
    ),
    ...
);
_

しかし、サーバーが連想配列ではなく通常の配列であることをサーバーが期待していた場合、セキュリティの脆弱性につながる可能性があります。

_//Simplified example, bug is possible with parameterized queries as well
//Expects ?pass[]=password1&pass[]=password2
$query = 'INSERT INTO users (index, password) ';
$parts = array();

foreach($_GET['user'] AS $index=>$value){
  parts[]=" VALUES ({$index}, ".$pdo->real_escape_string($value).')';
}

$query .= implode(", ", $parts);
$pdo->exec($query);//
_

_$query_と予想される入力:

_INSERT INTO USERS (index, password) VALUES(0, 'password1'), VALUES(1, 'password2')
_

_$query_と?pass[0,'');DROP DATABASE DATABASE();--]=foo

_INSERT INTO USERS (index, password) VALUES(0,'');DROP DATABASE DATABASE();--, 'foo')
_

BOOM.

事実、これは「Drupalgeddon」と呼ばれるセキュリティ上の欠陥につながるまったく同じ間違いです–および正当な理由でその名前を受け取りました。

このAPIの脆弱性により、攻撃者は特別に細工したリクエストを送信して、任意のSQL実行を引き起こす可能性があります。リクエストの内容によっては、特権の昇格、任意のPHP実行、またはその他の攻撃につながる可能性があります。 – SA-CORE-2014-005-Drupalコア-SQLインジェクション

SA-CORE-2014-005の発表から数時間以内にDrupal 7.32にパッチまたは更新されていないDrupal 7 Webサイトが侵害され、自動攻撃が開始されました-Drupalコア-SQLインジェクション。発表から7時間後の10月15日午後11時(UTC)より前に更新またはパッチを適用しない限り、すべてのDrupal 7 Webサイトが危険にさらされていると想定して続行する必要があります。 – Drupal Core-非常に重要-公共サービスの発表-PSA-2014-0

それも パナマペーパーの開示につながる可能性が最も高い脆弱性 (おそらくそれらのセキュリティ更新プログラムをインストールする必要があったはずです...)。

Drupalの脆弱性は、受信した配列を array_values() に渡すようにコードを更新することで修正され、値のみを含むインデックス付き配列を返します受け取った配列のを使用して、悪意のあるキーを取り除きます。

サンプルコードは同じ方法で修正できます:

前:

_foreach($_GET['user'] AS $index=>$value){
_

後:

_foreach(array_values($_GET['user']) AS $index=>$value){
_

実用的なエクスプロイトを含むDrupalgeddonの詳細: Drupal 7:Drupalgeddon Exploit

_$_GET_と_$_POST_のどちらを使用していても、この方法は同じように機能することに注意してください。 _$_REQUEST_と_$_COOKIE_についてはわかりません。

4
user2428118

MongoDBなどの他の攻撃の可能性があります。

$ _GET(または$ _POST)パラメータをクエリに渡す場合は、最初に文字列にキャストされていることを確認してください。ユーザーは、GETおよびPOSTリクエストに連想配列を挿入できます。これにより、不要な$クエリになることがあります。

かなり無害な例:リクエスト http://www.example.com?username=bob でユーザーの情報を検索するとします。アプリケーションはクエリ$ collection-> find(array( "username" => $ _GET ['username']))を実行します。

誰かが http://www.example.com?username [ $ ne] = fooを取得することでこれを覆すことができますPHPは魔法のように連想配列になります、クエリを$ collection-> find(array( "username" => array( '$ ne' => "foo")))に変換すると、 "foo"という名前のないすべてのユーザー(おそらくすべてのユーザー)が返されます。

http://php.net/manual/en/mongo.security.php

0
Xavier59