web-dev-qa-db-ja.com

マルチバイト文字の悪用-PHP / MySQL

MySQLのマルチバイト文字のエクスプロイトに関する情報へのリンクを誰かに教えてもらえますか?友人が私の注意を引きましたが、私はインターネットで多くの情報を見つけることができませんでした。

20
Matthew S

概要。はい、問題は、一部の文字エンコーディング(UTF-8など)で、単一の文字が複数のバイトとして表されることです。一部のプログラマーがSQLインジェクションを防止する1つの方法は、信頼されていない入力内のすべての単一引用符をエスケープしてから、SQLクエリに挿入することです。ただし、多くの標準的な引用エスケープ関数は、データベースがその文字列をバイトシーケンスとして使用および処理する文字エンコーディングを無視します。これは、単一の文字が数バイトを埋める可能性があるという事実とは関係ありません。これは、引用エスケープ関数が文字列をデータベースとは異なる方法で解釈していることを意味します。その結果、データベースが単一引用符のマルチバイトエンコーディングとして解釈する文字列の一部を引用符エスケープ関数がエスケープできない場合があります。または、以前は存在していなかった場所に単一引用符を導入するような方法で、マルチバイト文字エンコーディングを誤って分割する可能性があります。したがって、マルチバイト文字の悪用は、プログラマーがデータベースへの入力を適切にエスケープしているとプログラマーが思った場合でも、SQLインジェクション攻撃を実行する方法を攻撃者に与えます。

影響。prepared/parametrizedステートメントを使用してすべてのデータベース接続を形成する場合、安全です。マルチバイト攻撃は失敗します。 (もちろん、データベースとライブラリのバグを除外します。しかし、経験的には、それらはまれなようです。)

ただし、信頼できない入力をエスケープして、文字列連結を使用して動的にSQLクエリを作成しようとすると、マルチバイト攻撃に対して脆弱になる可能性があります。実際に脆弱かどうかは、使用するエスケープ関数、使用するデータベース、データベースで使用する文字エンコーディング、および場合によってはその他の要因の詳細に依存します。マルチバイト攻撃が成功するかどうかを予測するのは難しい場合があります。その結果、文字列連結を使用してSQLクエリを形成することは壊れやすく、推奨されません。

技術的な詳細。攻撃の詳細についてお読みになりたい場合は、攻撃を説明するリンクをいくつかご紹介します。詳細。いくつかの攻撃があります:

  • 引用機能によって導入された余分なバックスラッシュ/引用符を食べることによる、UTF-8やその他の文字エンコーディングなどの基本的な攻撃:たとえば、 here を参照してください。

  • GBKなどへの卑劣な攻撃は、引用機能をだまして追加の引用を導入することで機能します。たとえば、 Chris Shiflettのブログここ 、または-を参照してください。 ここ

  • 単一引用符の無効な非標準(長すぎる)エンコードを使用して引用符の存在を隠すUTF-8などの攻撃:たとえば、 here を参照してください。基本的に、単一引用符をエンコードする通常の方法は、シングルバイトシーケンス(つまり、0x27)に適合します。ただし、データベースが一重引用符としてデコードする可能性のあるマルチバイトシーケンスもあり、0x27バイトまたはその他の疑わしいバイト値が含まれていません。その結果、標準の引用エスケープ関数はこれらの引用をエスケープできない可能性があります。

20
D.W.

マルチバイト攻撃はSQLインジェクションに限定されません。一般的な意味では、マルチバイト攻撃は「バイト消費」状態を引き起こし、攻撃者は制御文字を削除します。これは、攻撃者が一重引用符の制御文字を導入する従来の_' or 1=1--_の反対です。 mysqlの場合、mysql_real_escape_string()があり、文字エンコードの問題に対処するように設計されています。 PDOのようなパラメーター化されたクエリライブラリは、この関数を自動的に使用します。 MySQLiは実際にはクエリのパラメーターを構造体内の個別の要素として送信するため、問題が完全に回避されます。

HTMLページがShift-JISを介してレンダリングされる場合、制御文字を使用してXSSを取得することが可能です。この優れた例は、207ページの「 A Tangled Web "(素晴らしい本!)」にあります。

_<img src="http://fuzzybunnies.com/[0xE0]">
...this is still a part of the mkarup...
...but the srever dosn't know...
" onload="alert('this will execute!')"
<div>
...page content continues...
</div>
_

この場合、0xE0は、3バイトのシンボルの開始を示す特別なバイトです。ブラウザがこのhtmlをレンダリングすると、流れる_">_が消費され、単一のShift-JISシンボルに変わります。攻撃者が別の変数を使用して次の入力を制御する場合、攻撃者はイベントハンドラーを導入してコード実行を取得できます。

5
rook