ホームページ  >  記事  >  データベース  >  一般的な SQL インジェクション方法

一般的な SQL インジェクション方法

L
L転載
2020-05-30 11:28:083012ブラウズ

一般的な SQL インジェクション方法

#一般的な SQL インジェクション方法

WEB セキュリティ SQL インジェクション

#はじめに: Web サイトを開発する場合、セキュリティ上の理由から、ページから渡される文字をフィルターする必要があります。通常、ユーザーは、URL アドレス バー、ログイン インターフェイス、メッセージ ボード、検索ボックスなどのインターフェイスを通じてデータベースのコンテンツを呼び出すことができます。これにより、ハッカーが悪用する機会が多くなります。最悪の場合、データが漏洩したり、サーバーがダウンしたりする可能性があります。

1. SQL インジェクションの手順

a) インジェクション ポイントを見つけて特別なステートメントを構築する

受信 SQL ステートメントの制御可能なパラメーターは分割されています

1. 数値型の場合、?id=1

2 のように、パラメータを引用符で囲む必要はありません。他の型の場合、?name のように、パラメータを引用符で囲む必要があります。 ="phone"

b) ユーザーは SQL ステートメント ('or 1=1#;admin'# など) を作成します (この挿入は PHP のユニバーサル パスワードとも呼ばれ、ユーザー名はわかっています)。後で説明します)

c) SQL ステートメントを DBMS データベースに送信します

d) DBMS は返された結果を受け取り、リクエストをマシン コード命令に解釈します。

e) DBMS 返された結果を受け入れ、処理してユーザーに返す

ユーザーは特別な SQL ステートメントを作成するため、特別な結果を (次のように) 返す必要があります。 SQL ステートメントが十分に柔軟である限り)

以下に、SQL インジェクションを詳しく説明するための例を示します

2. SQL インジェクションの例の詳細な説明 (上記のテストは、magic_quote_gpc がそうでないことを前提としています)
1) 事前準備

最初の SQL インジェクションの脆弱性を実証しましょう。バックエンド管理者インターフェイスにログインします。

まず、テスト用のデータ テーブルを作成します。

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`password` varchar(64) NOT NULL,
`email` varchar(64) NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

テスト用のレコードを追加します:

INSERT INTO users (username,password,email)VALUES('MarcoFly',md5('test'),'marcofly@test.com');

次に、ログインを貼り付けます。インターフェイスのソース コード

<html>
 <head> 
  <title>Sql注入演示</title> 
  <meta http-equiv="content-type" content="text/html;charset=utf-8" /> 
 </head> 
 <body> 
  <form action="validate.php" method="post"> 
   <fieldset> 
    <legend>Sql注入演示</legend> 
    <table> 
     <tbody>
      <tr> 
       <td>用户名:</td>
       <td><input type="text" name="username" /></td> 
      </tr> 
      <tr> 
       <td>密 码:</td>
       <td><input type="text" name="password" /></td> 
      </tr> 
      <tr> 
       <td><input type="submit" value="提交" /></td>
       <td><input type="reset" value="重置" /></td> 
      </tr> 
     </tbody>
    </table> 
   </fieldset> 
  </form>   
 </body>
</html>

レンダリングを添付します:

一般的な SQL インジェクション方法ユーザーが送信ボタンをクリックすると、フォーム データが validate.php ページに送信されます。validate.php ページは、ユーザーが入力したユーザー名とパスワードが要件を満たしているかどうかを判断するために使用されます (これはこのステップは非常に重要であり、多くの場合、SQL の脆弱性の場所です)

!                                         <!--前台和后台对接-->
<html>
<head>
<title>登录验证</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body>
<?php
$conn=@mysql_connect("localhost",&#39;root&#39;,&#39;&#39;) or die("数据库连接失败!");;
mysql_select_db("injection",$conn) or die("您要选择的数据库不存在");
$name=$_POST[&#39;username&#39;];
$pwd=$_POST[&#39;password&#39;];
$sql="select * from users where username=&#39;$name&#39; and password=&#39;$pwd&#39;";
$query=mysql_query($sql);
$arr=mysql_fetch_array($query);
if(is_array($arr)){
header("Location:manager.php");
}else{
echo "您的用户名或密码输入有误,<a href=\"Login.php\">请重新登录!</a>";
}
?>
</body>
</html>

お気づきですか? ユーザーを直接送信します。データ (ユーザー名とパスワード) は直接実行され、特殊文字フィルターが適用されます。これは致命的であることが後でわかります。

コード解析: ユーザー名とパスワードが一致した場合は管理者操作インターフェース(manager.php)にジャンプし、一致しなかった場合はわかりやすいプロンプトメッセージが表示されます。

成功したログイン インターフェイス:

一般的な SQL インジェクション方法 ログイン失敗のプロンプト:

一般的な SQL インジェクション方法 この時点で、準備作業は完了しました。完了しました。次にハイライトを開始します: SQL インジェクション

2) SQL ステートメントを構築します

正しいユーザー名 (marcofly) とパスワード (テスト) を入力した後、「送信」をクリックすると、結果が返されます。 「ようこそ管理者」インターフェイスへ。

送信したユーザー名とパスワードは次のように SQL クエリ ステートメントに合成されるため:

select * from users where username=&#39;marcofly&#39; and password=md5(&#39;test&#39;)

明らかに、ユーザー名とパスワードは前に指定したものと同じです。間違いなく正常にログインできます。しかし、間違ったユーザー名またはパスワードを入力した場合はどうなるでしょうか?当然ですが、ログインできません。これは通常の状況では当てはまりますが、SQL インジェクションの脆弱性がある Web サイトの場合は、特別な「文字列」が構築されている限り、正常にログインできます。



例: ユーザー名入力ボックスに ' または 1=1# と入力し、パスワードを何気なく入力します。この時点で合成された SQL クエリ ステートメントは次のとおりです:

select * from users where username=&#39;&#39; or 1=1#&#39; and password=md5(&#39;&#39;)

意味解析: "#" は mysql のコメント文字であるため、# 以降の内容は mysql によってコメント内容とみなされ実行されません。つまり、次の 2 つの SQL 文は価数:


select * from users where username=&#39;&#39; or 1=1#&#39; and password=md5(&#39;&#39;)

は、1=1 が常に true、つまり where 句が常に true であるため、

select* from users where usrername=&#39;&#39; or 1=1

と同等です。SQL をさらに単純化した後、など値は次の select ステートメントです:

select * from users

はい、この SQL ステートメントの機能は、users テーブルのすべてのフィールドを取得することです


上記は入力メソッドです。これはもう 1 つのインジェクション メソッドであり、このメソッドは PHP のユニバーサル パスワードとも呼ばれます

ユーザー名がわかっている場合は、パスワードなしでログインできます。ユーザー名が admin

であるとします。ステートメント:

select * from users where username=&#39;admin&#39;#&#39; and password=md5(&#39;&#39;)

select * from users where username=&#39;admin&#39;

と同等なので、パスワードを入力せずにログインできます。

データベースは、ユーザー名がなくてもログインできると誤って認識し、バックグラウンド検証をバイパスし、注入の目的を達成します。

は SQL 構文の脆弱性も悪用します。

ほら、構築された SQL ステートメントは非常に恐ろしい破壊力を持ちます。これを見れば、SQL インジェクションについて合理的に理解できるようになると思います~
はい、SQL インジェクションはとても簡単です。しかし、実際の状況に応じて柔軟な SQL 文を構築することはそれほど簡単ではありません。基本を理解したら、自分でゆっくりと探索してみてください。
バックグラウンド ログイン ウィンドウから送信されたデータが、管理者によって特殊文字を使用して除外されたらどうなるか考えたことはありますか?この場合、ユニバーサル ユーザー名または 1=1# は使用できません。しかし、これは何も対策がないということではなく、ユーザーがデータベースを操作する方法は複数あることを知らなければなりません。

推奨: 「mysql チュートリアル

以上が一般的な SQL インジェクション方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。