PHP常見漏洞(1)–SQL隱碼攻擊

技術小胖子發表於2017-11-08
SQL隱碼攻擊(SQL Injection),是攻擊者在表單中提交精心構造的sql語句,改動原來的sql語句,如果web程式沒有對提交的資料經過檢查,那麼就會造成sql注入攻擊。 


SQL隱碼攻擊的一般步驟: 
1、攻擊者訪問有SQL隱碼攻擊漏洞的站點,尋找注入點 
2、攻擊者構造注入語句,注入語句和程式中的SQL語句結合生成新的sql語句 3、新的sql語句被提交到資料庫中執行 處理 
4、資料庫執行了新的SQL語句,引發SQL隱碼攻擊

 

203600942.png

 

 

例項 

資料庫 

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 顯示留言 頁面 

http://www.netsos.com.cn/show.php?id=71 可能存在注入點,我們來測試

http://www.netsos.com.cn/show.php?id=71 and 1=1


203603611.png

 

 

 

203605740.png

 

 

 

一次查詢到記錄,一次沒有,我們來看看原始碼 
//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等函式進一步滲透。



防範方法 

整型引數: 運用 intval函式將資料轉換成整數
函式原型 
int intval(mixed var, int base) 
    var是要轉換成整形的變數 
    base,可選,是基礎數,預設是10 
浮點型引數: 
    運用 floatval或doubleval函式分別轉換單精度和雙精度浮點型引數 


函式原型 
int floatval(mixed var) 
    var是要轉換的變數 
int doubleval(mixed var)
    var是要轉換的變數 

字元型引數: 
運用 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”]); 



再次測試,漏洞已經修補!!! OK !


雖然國內很多PHP程式設計師仍在依靠addslashes防止SQL隱碼攻擊,還是建議大家加強中文防止SQL隱碼攻擊的檢查。addslashes的問題在 於黑客 可以用0xbf27來代替單引號,而addslashes只是將0xbf27修改為0xbf5c27,成為一個有效的多位元組字元,其中的0xbf5c仍會 被看作是單引號,所以addslashes無法成功攔截。
當然addslashes也不是毫無用處,它是用於單位元組字串的處理,多位元組字元還是用mysql_real_escape_string吧。

開啟magic_quotes_gpc來防止SQL隱碼攻擊
php.ini中有一個設定:magic_quotes_gpc = Off
   這個預設是關閉的,如果它開啟後將自動把使用者提交對sql的查詢進行轉換,
   比如把 ` 轉為 `等,對於防止sql注入有重大作用。
     如果magic_quotes_gpc=Off,則使用addslashes()函式
另外對於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個函式的區別:
mysql_real_escape_string 必須在(PHP 4 >= 4.3.0, PHP 5)的情況下才能使用。否則只能用 mysql_escape_string ,兩者的區別是:mysql_real_escape_string 考慮到連線的當前字符集,而mysql_escape_string 不考慮。
(1)mysql_real_escape_string — 轉義 SQL 語句中使用的字串中的特殊字元,並考慮到連線的當前字符集
使用方法如下:

$sql = “select count(*) as ctr from users where 

username02.=`”.mysql_real_escape_string($username).”` and 03.password=`”. 

mysql_real_escape_string($pw).”` limit 1″;


自定義函式

function inject_check($sql_str) { 
    return eregi
(`select|insert|and|or|update|delete|`|/*|*|../|./|union|into|load_file|outfile`, $sql_str);
 } 
 function verify_id($id=null) { 
    if(!$id) {
         exit(`沒有提交引數!`); 
    } elseif(inject_check($id)) { 
        exit(`提交的引數非法!`);
     } elseif(!is_numeric($id)) { 
        exit(`提交的引數非法!`); 
    } 
    $id = intval($id); 
    return $id; 
 function str_check( $str ) { 
    if(!get_magic_quotes_gpc()) { 
        $str = addslashes($str); // 進行過濾 
    } 
    $str = str_replace(“_”, “_”, $str); 
    $str = str_replace(“%”, “%”, $str); 
   return $str; 
 function post_check($post) { 
    if(!get_magic_quotes_gpc()) { 
        $post = addslashes($post);
     } 
    $post = str_replace(“_”, “_”, $post); 
    $post = str_replace(“%”, “%”, $post); 
    $post = nl2br($post); 
    $post = htmlspecialchars($post); 
    return $post; 
}


對於這些修改網站程式碼的情況,還可使使用一些防注入的工具,像安全狗實驗室出的安全狗對於防注入就非常的強大,可以攔住不少的入侵者的腳步。同樣還有一些的防注入工具也很強大,大家可以去試試!

END!!!


     本文轉自Tar0 51CTO部落格,原文連結:http://blog.51cto.com/tar0cissp/1281140,如需轉載請自行聯絡原作者


相關文章