SQL注入繞過PHP單引號字元轉義原理及預防方法

2021-06-28 01:02:25 字數 2216 閱讀 3571

利用gbk雙位元組編碼,繞過單引號轉義

附贈工具一款:php漢字url編碼轉換器

/* 注入實驗:start */

$id = $_get['id'];

//建立連線

$conn = false;

$conn = mysql_connect("localhost","root","");

mysql_query("set names 'gbk'");

mysql_select_db("test", $conn);

//執行

$sql = "select id,name from table where id = '".$id."' limit 1";

if(!($query = mysql_query($sql,$conn)))

$result = array();

while($row = mysql_fetch_array($query,mysql_assoc))

echo '$id:'.$id."\n";

echo '$sql:'.$sql."\n";

print_r($result);

/* 注入實驗:end */

url:http://localhost/a.php?id=10%20and%201=2

sql:

select downid,name from x_downs where projectid = '10 and 1=2' limit 1
其中由於projectid = 『$id』被單引號括住了,1=2,1=1暫時失效了

不過我們可以通過漢字雙位元組編碼進行注入

select downid,name from x_downs where projectid = '10謀' and 1=2#' limit 1
可以看到在前面加了個%d6後,引號被吃掉了

php會針對url編碼進行decode

decode後,url引數為 ?id=10 0xd6 『 0×20 and 0×20 1=2 0×23

magic_quotes_gpc處理時會自動轉義,即在前面加乙個\

處理後url引數變成: ?id=10 0xd60x5c『 0×20 and 0×20 1=2 0×23

可以看到,在前面php會自動加乙個0x5c(注:0x5c為\),也就是會自動轉義成\』

由於漢字是雙位元組的,所以0xd6 0x5c被轉為這個漢字,』之前的\就這樣消失了

最後的%23#,在sql中#是注釋,所以後面的』就沒用了

最終sql中projectid = 』10謀』在sql執行的時候,由於projectid為int型別字段,mysql會自動intval()處理一下 詳情見這裡

所以等效於

select downid,name from x_downs where projectid = 10 and 1=2
達到我們成功注入的目的

兩種1.對使用者的輸入資訊嚴格檢查和過濾

2.針對本方法,進行如下修改

(1)切勿在連線設定字符集時:set names 『gbk』

(2)當有類似設定時character_set_connection=gbk, character_set_results=gbk, character_set_client=binary

將character_set_client必須設定為binary

注:主要作用是在傳輸資料時使用binary的形式,避免了由於php將0xd6和0x5c合成乙個漢字的問題

繞過單引號繼續注入

web 應用程式一般都會使用資料庫來儲存各種資訊,比如電子商務 的帳戶資訊 銷售商品的 訂單 支付細節 和各種不同的許可權數值等。資料庫中的資訊的讀取 更新 增加或者刪除等都是通過 sql來實現的,因此,在資料互動的環節沒有安全過濾淨化,則可能易於受到 sql注入攻擊,嚴重的可能導致資料庫非法操作,...

自動完成 SQL注入單引號

在做查詢自動完成 autocomplete 功能時,出現乙個小bug。如下圖所示 這個錯誤很明顯是sql語句語法錯誤引起的,我這裡後端用的是字串拼接方式生成sql語句,其中部分條件模糊查詢語句如下 sql string.format and name like or shortname like o...

SQL 轉義字元 單引號

c 的轉義字元是 sql 的轉義字元是 單引號 例 select from tbl where uyear 06 請注意其中紅色背景的單引號,它即表示轉義字元,如果我們省略,則整個語句會出錯,轉義字元不會輸出,上例中 uyear 的實際條件值為 06,而不是 06 為什麼不能省略呢,假如我們省略,上...