phpにおけるsql注入脆弱性の例sql注入脆弱性の修復

4990 ワード

Webサイトを開発する際には、セキュリティ上、ページから渡される文字をフィルタリングする必要があります.通常、ユーザは、URLアドレスバー、ログインインタフェース、伝言板、検索ボックスなどのインタフェースを介してデータベースの内容を呼び出すことができる.これは往々にしてハッカーに乗る機会を残した.軽ければデータが漏れ、重ければサーバーが取り外される.一、SQL注入の手順
a)注入点を探す(例えば:ログインインタフェース、伝言板など)
b)ユーザー自身がSQL文を構築する(例えば:'or 1=1#、後で説明する)
c)sql文をデータベース管理システム(DBMS)に送信する
d)DBMSは要求を受信し、その要求をマシンコード命令と解釈し、必要なアクセス操作を実行する
e)DBMSは、返された結果を受け取り、処理してユーザに返す
ユーザーが特殊なSQL文を構築したため、必ず特殊な結果を返します(あなたのSQL文が柔軟であれば).
次に、SQL注入の例を示します.
二、SQL注入インスタンスの詳細(以上のテストはすべてサーバーがmagic_quote_gpcを開いていないと仮定する)
1)前期準備
まず、SQLで脆弱性を注入し、バックグラウンド管理者インタフェースにログインする方法を説明します.
まず、試験用のデータテーブルを作成します.
 
  
CREATETABLE `users` (

`id`int(11) NOT NULL AUTO_INCREMENT,

`username`varchar(64) NOT NULL,

`password`varchar(64) NOT NULL,

`email`varchar(64) NOT NULL,

PRIMARYKEY (`id`),

UNIQUEKEY `username` (`username`)

)ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;


テスト用のレコードを追加します.
 
  
INSERTINTO users (username,password,email)

VALUES('MarcoFly',md5('test'),'[email protected]');


次に、ログイン画面のソースコードを貼り付けます.
 
  


Sql




 

    Sql
   
     
       
       
     
     
       
       
     
     
       
       
     
   
   :

 





ユーザがコミットボタンをクリックすると、フォームデータがvalidateにコミットされる.phpページ、validate.phpページは、ユーザーが入力したユーザー名とパスワードが要求に合っているかどうかを判断するために使用されます(このステップは重要ですが、SQLの脆弱性もよくあります).
コードは次のとおりです.
 
  





       $conn=@mysql_connect("localhost",'root','')or die(" !");;

      mysql_select_db("injection",$conn) or die(" ");

      $name=$_POST['username'];

      $pwd=$_POST['password'];

      $sql="select * from users where username='$name' andpassword='$pwd'";

      $query=mysql_query($sql);

      $arr=mysql_fetch_array($query);

      if(is_array($arr)){

             header("Location:manager.php");

       }else{

             echo " , ログインしてください!";

       }

?>



いいえ、ユーザーが提出したデータ(ユーザー名とパスワード)を直接実行し、特殊な文字フィルタリングを実現していません.これは致命的であることがわかります.
コード分析:ユーザー名とパスワードの一致に成功すると、管理者操作インタフェース(manager.php)にジャンプし、成功しない場合は、友好的なヒントを与えます.
ここまで来て、前期の仕事はすでに完成して、次は私达のメインの芝居を展开します:SQL注入
2)SQL文の構築
正しいユーザー名(marcofly)とパスワード(test)を記入したら、「提出」をクリックすると、「管理者歓迎」のインタフェースに戻ります.
私たちが提出したユーザー名とパスワードに基づいてSQLクエリー文に合成された後、次のようになります.
 
  
select * from users where username='marcofly' andpassword=md5('test')

明らかに、ユーザー名とパスワードは私たちが前に与えたものと同じで、ログインに成功するに違いありません.しかし、もし私たちが間違ったユーザー名やパスワードを入力したら?明らかに、登録できないでしょう.はい、通常はそうですが、SQLの脆弱性があるサイトでは、特殊な「文字列」を構築すれば、正常にログインできます.
例えば、ユーザー名入力ボックスに「or 1=1#」と入力し、パスワードを勝手に入力すると、合成後のSQLクエリ文は次のようになります.
 
  
select * from users where username='' or 1=1#' and password=md5('')

意味分析:「#」はmysqlでアノテーション記号であり、井戸番号の後ろの内容はmysqlでアノテーション内容と見なされ、実行されません.言い換えれば、以下の2つのsql文は等価です.
 
  
select * from users where username='' or 1=1#' and password=md5('')

に等しい
 
  
select *from users where username='' or 1=1

1=1は常に成立するため、where句は常に真であり、このsqlをさらに簡略化した後、次のselect文に等価である.
 
  
select * from users

そうです.このsql文の役割はusersテーブルのすべてのフィールドを取得することです.
テクニック:'or 1=1#の一重引用符の役割を知らなければ、自分でsql文をechoすることができて、一目瞭然です.
见たでしょう、1つの构造したsqlの文は意外にもこのような恐ろしい破壊力があって、あなたがこれを见た后に、sqlに対して1つの理性的な认识があることを注入することを信じます
そう、SQL注入はこんなに簡単です.しかし,実際の状況に応じて柔軟なsql文を構築することは容易ではない.基礎ができたら、自分でゆっくり模索しましょう.
バックグラウンドログインウィンドウを介して送信されたデータが管理者によって特殊文字がフィルタリングされた後、考えたことはありますか?これでは、私たちの万能ユーザー名'or 1=1#は使用できません.しかし、これは私たちが対策がないわけではありません.ユーザーがデータベースと付き合う方法はこれだけではありません.