SQL インジェクションは、攻撃者が既存の SQL クエリに追加の論理式やコマンドを追加できるようにする攻撃であり、ユーザーが送信したデータが誤って検証され、正規の SQL クエリでスタックされている場合に成功する可能性があります。インジェクション攻撃は PHP の問題ではなく、プログラマの問題です。
SQL インジェクション攻撃の一般的な手順:
1. 攻撃者はSQLインジェクションの脆弱性のあるサイトを訪問し、インジェクションポイントを探す
2. 攻撃者がインジェクション文を構築し、そのインジェクション文がプログラム内のSQL文と結合されて新たなSQL文が生成される
3. 新しい SQL ステートメントが実行のためにデータベースに送信されます
4. データベースが新しい SQL ステートメントを実行し、SQL インジェクション攻撃をトリガーしました
例
データベース
CREATE TABLE `postmessage` (
`id` int(11) NOT NULL auto_increment,
`subject` varchar(60) NOT NULL デフォルト ",
`name` varchar(40) NOT NULL デフォルト ",
`email` varchar(25) NOT NULL デフォルト ",
「質問」メディアテキストが NULL ではありません、
`postdate` datetime NOT NULL デフォルト '0000-00-00 00:00:00',
主キー(`id`)
) ENGINE=MyISAM DEFAULT CHARSET=gb2312 COMMENT='ユーザーのメッセージ' AUTO_INCREMENT=69;
ch3.* のすべての権限を「123456」で識別される「sectop」@localhost に付与します。
//add.php メッセージを挿入
//list.phpメッセージリスト
//show.php メッセージを表示します
ページ /show.php?id=71 にインジェクションポイントがある可能性がありますので、テストしてみましょう
/show.php?id=71と1=1
ページに戻る
レコードがクエリされた後、レコードが存在しなくなったので、ソースコードを見てみましょう
//show.php 12~15行目
// mysqlクエリ文を実行
$query = "select * from postmessage where id = ".$_GET["id"];
$result = mysql_query($query)
または die("ySQL クエリ ステートメントの実行に失敗しました: " . mysql_error());
パラメータIDが渡された後、前の文字列と結合されたSQLステートメントがデータベースに入れられ、クエリが実行されます
Submit and 1=1 とすると、ステートメントは select * from postmessage where id = 71 and 1=1 となり、このステートメントの前後の値は両方とも true、その後の and も true になり、クエリされたデータが返されます
Submit と 1=2 の場合、ステートメントは select * from postmessage where id = 71 and 1=2 になります。このステートメントの最初の値は true、最後の値は false、次の値は false となり、データは存在しません。質問されました
通常の SQL クエリは、構築したステートメントを渡した後、SQL インジェクション攻撃を形成します。このインジェクションポイントを通じて、union を使用して管理パスワードを読み取る、データベース情報を読み取る、または mysql のload_file を使用するなどの権限を outfile やその他の関数にさらに取得して、さらに侵入することができます。
アンチSQLインジェクション方法
$id = intval ($_GET['id']);
もちろん、他の変数タイプもあります。必要に応じて、フォーマットを強制してみてください。
キャラクターパラメータ:
addslashes 関数を使用して、一重引用符 "'" から "'"、二重引用符 """ から """、バックスラッシュ "" から ""、バックスラッシュ付きの NULL 文字 "" を変換します
関数プロトタイプ
文字列はスラッシュを追加します(文字列 str)
Strはチェック対象の文字列です
その後、このようにして現れたコードの脆弱性を修正できます
// mysqlクエリ文を実行
$query = "select * from postmessage where id = ".intval($_GET["id"]);
$result = mysql_query($query)
or die("ySQL クエリ ステートメントの実行に失敗しました: " .mysql_error());
文字タイプの場合は、最初に magic_quotes_gpc を On にできるかどうかを判断します。 On にできない場合は、addslashes を使用して特殊文字をエスケープします。
コードをコピー | |||||||||||||||||
if(get_magic_quotes_gpc()) { $var = $_GET["var"]; } その他 { $var =addslashes($_GET["var"]); } ]
|
コードは次のとおりです | コードをコピー |
SELECT * FROM 記事 WHERE 記事 ID = '$id' SELECT * FROM 記事 WHERE 記事 ID = $id |
どちらの記述方法もさまざまなプログラムで共通ですが、最初の文では変数 $id が一重引用符で囲まれているため、正しい SQL ステートメントであっても、送信する変数は文字列になります。 2 番目の文は異なります。変数は一重引用符で囲まれていないため、スペースが含まれている限りすべて SQL ステートメントとして扱われます。そのため、追加する習慣を身に付ける必要があります。 SQL ステートメント内の変数を引用符で囲みます。
3. URL 擬似静的
URL 擬似静的とは、Discuz のような URL 書き換えテクノロジーです。同様に、すべての URL を xxx-xxx-x.html のような形式に書き換えることをお勧めします。これは SEO に有益であり、一定レベルのセキュリティを実現します。ただし、PHP での SQL インジェクションを防止したい場合は、特定の「通常の」基盤が必要です。
4. PHP 関数を使用してフィルタリングとエスケープを行う
PHP での SQL インジェクションのより重要な点は、GPC の設定です。MYSQL4 より前のバージョンではサブステートメントがサポートされておらず、php.ini の magic_quotes_gpc が On の場合、送信された変数内のすべての " ' " (単一) が引用符で囲まれるためです。 )、" " " (二重引用符)、" " (バックスラッシュ)、および null 文字はバックスラッシュを含むエスケープ文字に自動的に変換され、SQL インジェクションに多くの障害をもたらします。
5. PHPのMySQL関数を使用してフィルタリングとエスケープを行う
PHP の MySQL 操作関数には、addslashes()、mysql_real_escape_string()、mysql_escape_string() およびその他の関数が含まれており、特殊文字やデータベース操作エラーを引き起こす可能性のある文字をエスケープできます。
それでは、これら 3 つの機能の違いは何でしょうか?以下で詳しく説明しましょう:
① addslashes の問題は、ハッカーが単一引用符の代わりに 0xbf27 を使用できることですが、addslashes は有効なマルチバイト文字と呼ばれる 0xbf27 を 0xbf5c27 に変更するだけであり、0xbf5c は依然として単一引用符とみなされます。そのため、addslashes は正常に を傍受できません。
もちろん、addslashes は、マルチバイト文字の処理に使用されます。mysql_real_escape_string を使用します。
さらに、PHP マニュアルの get_magic_quotes_gpc の例:
コードは次のとおりです | コードをコピー |
if(!get_magic_quotes_gpc()){ $lastname =addslashes($_POST['lastname']);}else{ $lastname = $_POST['lastname'];} |
magic_quotes_gpc がすでにオンになっている場合は、$_POST['lastname'] を確認することをお勧めします。
2 つの関数 mysql_real_escape_string と mysql_escape_string の違いについて話しましょう:
コードは次のとおりです | コードをコピー | ||||||||||||||||
関数dadslashes($string, $force = 0, $strip = FALSE) { if(!MAGIC_QUOTES_GPC || $force) { if(is_array($string)) { foreach($string as $key => $val) { $string[$key] = ダッズラッシュ($val, $force, $strip); } }その他 { $string = ラッシュを追加します($strip ? ストリップスラッシュ($string) : $string); } } $string を返します; } コマンド1 - 任意のファイルを書き込む MySQL には、システム ファイルの作成と書き込みに使用できるコマンドが組み込まれています。 このコマンドの形式は次のとおりです:
このコマンドの大きな欠点は、UNION SQL トークンを使用して既存のクエリに追加できることです。 たとえば、次のクエリに追加できます:
上記のコマンドの結果として、クエリ結果を含む /tmp/file.txt ファイルが作成されます。
ウェブシェル Webshell は、Web ブラウザーのシェルからコマンドを実行するための人気があり、広く使用されているツールです。これらのツールを PHP シェルと呼ぶ人もいます。 シェル コマンドを実行する非常に単純な Web シェルを作成します。 これは、非常に基本的な PHP シェルが実行するコードです (パラメータは california に渡されます):
|