SQLインジェクション。 検証、ハッキング、保護

SQLインジェクションは、サイトをハッキングする最も手頃な方法の1つです。

このような注入の本質は、データへの任意のSQLコードの実装です(GET、POST要求、またはCookie値を介して送信されます)。 サイトが脆弱であり、そのような注入を実行する場合、実際にはデータベース(ほとんどの場合MySQL)から何かを作成する機能があります。



SQLインジェクションを注入する脆弱性の計算方法



とても簡単です。 たとえば、テストサイトtest.ruがあります。 サイトには、詳細なプロモトラの可能性を伴うニュースのリストが表示されます。 ニュースの詳細な説明が記載されたページのアドレスは、 test.ru / ?detail=1のようになります。 つまり、GETリクエストを介して、変数detailは値1(ニューステーブルのエントリの識別子)を転送します。



GETリクエストを?detail=1'



または?detail=1"



ます。次に、これらのリクエストをサーバーに送信します。つまり、 test.ru / ?detail ?detail=1"



'またはtest.ru/?detail=1 "に移動します。



これらのページにアクセスするときにエラーが発生した場合、サイトはSQLインジェクションに対して脆弱です。



脆弱性をチェックするときに発生するエラーの例

画像



可能なSQLインジェクション(SQLインジェクション)

1)最も単純なものは、WHERE条件をパラメーター値の真の結果に最小化することです。

2)別のクエリのクエリ結果を結合します。 これは、UNION演算子を介して行われます。

3)リクエストの一部をコメントアウトします。



練習。 SQLインジェクションの脆弱性によるサイトオプションのハッキング



したがって、すでに言及したサイトtest.ruがあります。 データベースには4つのニュースが保存され、そのうち3つが表示されます。 ニュースを公開する権限は、パブリックパラメーターによって異なります(パラメーターに値1が含まれている場合、ニュースが公開されます)。



掲載が許可されているニュースのリスト

画像



4番目のニュースを表示するページtest.ru/?detail=4にアクセスすると、エラーが表示されます-ニュースが見つかりませんでした。

私たちの場合、ニュースは存在しますが、公開は禁止されています。

画像



しかし、すでにサイトの脆弱性をチェックし、DBエラーを生成したため、可能なクエリオプションを並べ替えようとしています。

アドレスバーでは、プラス(+)がスペースとして機能するため、怖がらないでください



次のオプションをテストしています。

test.ru/?detail=4+OR+1

test.ru/?detail=4+--

test.ru/?detail=4+UNION+SELECT+ * + FROM +ニュース+ WHERE + id = 4



その結果、運が微笑んで、2つのリクエスト(1番目と3番目)から4番目のニュースの詳細な説明が返されました。

画像



内部からの例の解析



コードブロックは、ニュースの詳細な説明を取得します。

$detail_id=$_GET['detail'];

$zapros="SELECT * FROM `$table_news` WHERE `public`='1' AND `id`=$detail_id ORDER BY `position` DESC";








$ detail_idは処理を行わずに値を取得するだけでなく、 `id` = $ detail_idコンストラクトも曲がっています。`id`= '$ detail_id'に固執することをお勧めします(つまり、比較した値を直接アポストロフィで書き込みます)。



ページにアクセスするときに受け取ったリクエストを見る test.ru/?detail=4+OR+1



SELECT * FROM `news` WHERE `public`='1' AND `id`=4 OR 1 ORDER BY `position` DESC








4番目のニュースが表示された理由は明らかではありません。 実際には、クエリはニューステーブルからすべてのエントリを返し、上から降順に並べ替えられます。 そして、私たちの4番目のニュースが非常に最初であることが判明し、それも詳細に表示されました。 すなわち単なる偶然です。



アクセス時に生成されたリクエストを解析する test.ru/?detail=4+UNION+SELECT+*+FROM+news+WHERE+id=4



test.ru/?detail=4+UNION+SELECT+*+FROM+news+WHERE+id=4







ここで、ニュース(この場合はニュース)を含むテーブルの名前は、論理的な列挙によって取得されました。

そのため、クエリSELECT * FROM `news` WHERE `public`='1' AND `id`=4 UNION SELECT * FROM news WHERE id=4 ORDER BY `position` DESC



。 4番目のニュースの詳細な説明を返す2番目の部分(UNIONの後)の結果は、要求の最初の部分(UNIONの前)のゼロ結果に加わりました。



SQLインジェクションに対する保護(SQLインジェクション)



ハッキングに対する保護は、「信頼するが検証する」という基本的なルールに基づいています。 あなたはすべてをチェックする必要があります-数字、行、日付、特別な形式のデータ。



数字


変数の数値を確認するには、is_numeric(n);関数を使用します(nが数値の場合はtrue、そうでない場合はfalseを返します)。

数値の値を確認することはできませんが、手動でタイプをオーバーライドすることもできます。 $ _GET ['id_news']から取得した$ id値を整数型の値(整数)にオーバーライドする例を次に示します。

$id=(int)$_GET['id_news'];









SQLハックのほとんどは、文字列に「無害な」引用符、アポストロフィ、およびその他の特殊文字が存在するためです。 これを行うには、各特殊文字の前にバックスラッシュ(\)を追加した文字列$ strを返す、addslashes($ str);関数を使用します。 このプロセスは適応と呼ばれます。



$a=" ' ";

echo addslashes($a); // : \'








さらに、SQL式で使用される文字列の適応のために特別に作成された2つの関数があります。

これはmysql_escape_string($ str)です。 およびmysql_real_escape_string($ str);。



1つ目はデータベース接続のエンコードを考慮していないためバイパスできますが、2つ目はデータベース接続のエンコードを考慮しており、完全に安全です。 mysql_real_escape_string($ str); 次の文字にバックスラッシュを追加した文字列$ strを返します: \x00, \n, \r, \, ', " \x1a







マジッククオート



マジッククォートは、I / O操作中に引用符をバックスラッシュ(\)と引用符に自動的に置き換える効果です。 一部のPHP構成では、このオプションが有効になっていますが、そうでない場合もあります。 mysql_real_escape_string($ str)を介した通常の方法での二重エスケープ文字とデータのエスケープを回避するには、自動バックスラッシュを削除する必要があります(マジッククオートがオンになっている場合)。



GET、POST、またはCookieから受信したデータのマジッククォートを含めるかどうかの確認は、 get_magic_quotes_gpc();



関数を使用して整理しますget_magic_quotes_gpc();



(マジッククオートが有効な場合は1、無効な場合は0を返します)。



マジッククオートが含まれている場合(つまり、バックスラッシュが追加されている場合)、これがより頻繁に発生する場合は、それらを削除する必要があります。 これは、ストリップスラッシュ($ str)関数を介して行われます。 (引用符とバックアポストロフィでバックスラッシュなしで文字列$ strを返します)。



結論として、データベースに書き込むための文字列のフルスクリーンバージョンを含むコードを提供します



if(get_magic_quotes_gpc()==1)

{

$element_title=stripslashes(trim($_POST["element_title"]));

$element_text=stripslashes(trim($_POST["element_text"]));

$element_date=stripslashes(trim($_POST["element_date"]));

}

else

{

$element_title=trim($_POST["element_title"]);

$element_text=trim($_POST["element_text"]);

$element_date=trim($_POST["element_date"]);

}



$element_title=mysql_real_escape_string($element_title);

$element_text=mysql_real_escape_string($element_text);

$element_date=mysql_real_escape_string($element_date);








この記事は、Webシステムを保護する実践的なスキルに基づいて作成されました。 理論は良いことですが、実践はより重要であり、最も重要なことはそれが機能することです。



All Articles