プログラマは、コードを記述するときに TDD (テスト駆動開発) に注意します。関数を実装する前に、まずテスト ケースを作成し、次にそれを実行するコードを作成します。実際、ハッカーが SQL インジェクションを実行するときも、TDD プロセスです。ハッカーはまずプログラムにエラーを報告させようとし、次にプログラムが再度正常に実行されると、インジェクションは成功します。 。
攻撃:
プログラムに次のようなスクリプトがあるとします。
$sql = "SELECT ID、タイトル、コンテンツ FROM 記事 WHERE id = {$_GET['id']}";
通常アクセス時のURLは以下の通りです。
/articles.php?id=123
ハッカーは SQL インジェクションの脆弱性があるかどうかを判断する場合、最も一般的な方法は整数 ID の後に一重引用符を追加することです:
/articles.php?id=123'
$_GET[ 'id'] パラメーターをフィルターしなかったため、次のような情報のようなエラーが必然的に報告されます:
指定された引数は...
この情報はスクリプトを説明するのに十分です。抜け穴があります。いくつかのトリックを使用できます:
/articles.php?id=0 Union select 1,2,3
1,2,3 が選択される理由は、結合要件のためです。 両側のフィールドの数は同じです。前に id、title、content の 3 つのフィールドがあり、1、2、3 つのフィールドがあります。また、id=0 を設定した場合、存在しないレコードの場合、結果は 1、2、3 になります。Web ページに反映されると、1 になります。本来のidが表示される場所には が表示され、タイトルが表示される場所には 2 が表示され、コンテンツが表示される場所には 3 が表示されます。
引き続き使用する方法については、magic_quotes_gpc:
magic_quotes_gpc がオフの場合:
/articles の設定にも依存します。 php?id=0 Union select 1,2,load_file('/etc/passwd')
このようにして、/etc/passwd ファイルの内容が、元に表示されていた場所に表示されます。
magic_quotes_gpc がオンの場合:
この時点で直接load_file('/etc/passwd')を使用すると、一重引用符がエスケープされるため無効になります。しかし、まだ方法はあります:
/articles.php?id=0 Union select 1,2,load_file(char(47,101,116,99,47,112,97,115,115,119,100))
その数字は/etc /passwd string ASCII: 文字列の各文字が周期的に出力されます ord(...)
これに加えて、文字列の 16 進数も使用できます: 文字列の各文字が周期的に出力されますdechex( ord(...))
/articles.php?id=0 Union select 1,2,load_file(0x2f6574632f706173737764)
ここでは、数値パラメーターに対する攻撃方法をいくつか紹介します。文字列パラメータなどの攻撃手法については、以下のリンク先のドキュメントを参照してください。
防御:
SQL インジェクション ファイアウォールに似たソフトウェアがインターネット上で利用可能です (GreenSQL など)。Web サイトが SQL インジェクション攻撃を受け始めている場合は、このショートカット ツールを使用すると、多くの場合、命が救われます。ただし、このようなソフトウェアは、そのアーキテクチャでプロキシの役割を果たし、Web サイトの同時パフォーマンスに影響を与える可能性があるため、選択するときは客観的な条件に基づいて慎重に決定することが最善です。それを選ぶかどうか。多くの場合、専門的なソフトウェアは必要なく、軽量なソリューションが多数あります。ここでは、awk を使用して潜在的な脆弱性を検出する方法を示します。
次の内容を含む detect_sql_injection.awk スクリプトを作成します (内容をコピーする場合は、行番号を含めないでください):
01 #!/bin/gawk - f02
03 /$_(GETPOSTCOOKIEREQUEST)s*[/ {
04 IGNORECASE = 1
05 if (match($0, /$.*(sqlquery)/)) {
06 IGNORECASE = 0
07 出力()
08 次
09 }
10 }
11
12 関数出力()
13 {
14 $1 = $1
15 print "CRUD: " $0 "nFILE: " FILENAME "nLINE: " FNR "n"
16 }
このスクリプトは、次のような問題コードに一致します。マッチング モードを拡張したい場合は、それも可能です。猫の例に従って if match ステートメントを書くだけです。簡単です。
1: $sql = "SELECT * FROM ユーザー WHERE username = '{$_POST['username']}'";2: $res = mysql_query("SELECT * FROM users WHERE username = '{$_POST['username']}'");
使用する前に chmod +x detect_sql_injection.awk を忘れずに行ってください。呼び出し方法は 2 つあります:
1: ./detect_sql_injection.awk /path/to/php/script/file2: find /path/to/php/script/directory -name "*.php" xargs ./detect_sql_injection .awk
は、次のように問題のあるコード情報を表示します:
CRUD: $sql = "SELECT * FROM users WHERE username = '{$_POST[' username ']}'";FILE: /path/to/file.php
LINE: 123
このスクリプトを実際の環境に適用するには、次のような方法があります。 CRON プログラムのソース ファイルを定期的にスキャンするか、SVN の送信時にフック メソッドを通じて自動的にソース ファイルを照合します。
専門的なツールを使用する場合でも、スクリプトを検出する場合でも、問題の根本は常にプログラマが必要なセキュリティ意識を持っているかどうかに依存します。
1: intval や floatval などのメソッドを使用して、数値パラメーターを強制的にフィルターします。
2: mysql_real_escape_string などのメソッドを使用して、単純なアッドスラッシュの代わりに文字列パラメーターを強制的にフィルターします。
3: mysql_query などのスプライシング SQL クエリ方式を放棄し、可能な限り PDO のバインディング準備メソッドを使用するのが最善です。
4: 書き換えテクノロジーを使用して実際のスクリプトとパラメーターの情報を隠し、通常の書き換えルールを通じて疑わしいパラメーターをフィルターします。
5: エラー プロンプトをオフにし、攻撃者に機密情報を提供しません: display_errors=off。
6: エラー情報をログ形式で記録します: log_errors=on および error_log=filename Web ログも定期的に確認することをお勧めします。
7: MySQL への接続に FILE 権限を持つアカウント (root など) を使用しないでください。これにより、load_file などの危険な関数がブロックされます。
8:...
Web サイトのセキュリティは実際には複雑ではありません。入力をフィルターし、出力をエスケープするという一文に要約できます。 このうち、これまで議論してきた SQL インジェクションの問題は、入力のフィルタリングの問題に属し、出力のエスケープの問題としては、クロスサイト スクリプティングが代表的ですが、この記事の範囲には含まれません。 , なのでこれ以上は言いません。
ドキュメント:
addslashes() と mysql_real_escape_string()
MySQL による SQL インジェクション
MySQL による高度な SQL インジェクション
MySQL インジェクションのフィールドのエクスポートコンテンツリサーチ - インジェクションによる WebShell のエクスポート